У вашего сценария много проблем. Во-первых, ваша внешняя команда find
не делает то, что вы ожидаете: она выводит не только каждый из подкаталогов, но и корень поиска, .
, который сам является каталогом. Вы могли бы обнаружить это, выполнив команду вручную, среди прочего. Вам не нужно использовать find
для этого, но предположим, что вы сделать использовать его, это было бы лучше:
for d in $(find * -maxdepth 0 -type d); do
Кроме того, .
является первый результат оригинального find
команды, и ваши проблемы продолжаются. Ваш начальный cd
не имеет значимого эффекта, потому что вы просто переходите в тот же каталог, в котором вы уже находитесь. Команда find
во внутреннем цикле коренится там и спускается в оба подкаталога. Поэтому информация о пути для каждого файла, который вы выбираете для переименования, разделяется sed
, поэтому результаты заканчиваются в начальном рабочем каталоге (./subdir1/001myfile001A.txt
->myfile001A.txt
). К тому времени, когда вы обрабатываете подкаталоги, в них нет файлов, которые можно переименовать.
Но это еще не все: команда find
неверна в вашей внутренней петле. Поскольку вы не указываете опцию перед этим, find
интерпретирует "*.txt"
как обозначение второго корня поиска, в дополнение к .
. Предположительно вы хотели использовать -name "*.txt"
для фильтрации результатов поиска; без него find
выводит имя каждого файла в дереве. Предположительно, вы подавляете или игнорируете полученные сообщения об ошибках.
Но если предположить, что ваши подпапки не имеют подкаталоги своей собственной, как показано на рисунке, и что вы не связаны с, даже составляют скрытые этой исправленной версии ...
for f in `find . -name "*.txt"`;
... это ужасно тяжеловес способ сказать это ...
for f in *.txt;
... или даже это ...
for f in *?myfile*.txt;
... последний из которых будет избегать попыток переименовать любые файлы, имена которых фактически не меняются.
Кроме того, запуск sed
процесса для каждого имени файла довольно расточительно и дорого, когда вы могли бы просто использовать bash's
встроенные подстановки функции:
mv "$f" "${f/#*myfile/myfile}"
И вы также обнаружите, что ваш рабочий каталог испортится , Рабочий каталог является характеристикой общей среды оболочки, поэтому он не автоматически сбрасывается на каждой итерации цикла. Вам нужно будет каким-то образом обработать это вручную. pushd
/popd
сделал бы это, как и тело внешнего цикла в подоболочке.
В целом, это будет делать трюк:
#!/bin/bash
for d in $(find * -maxdepth 0 -type d); do
pushd "$d"
for f in *.txt; do
mv "$f" "${f/#*myfile/myfile}"
done
popd
done
я был испорчен для выбора правильных ответов, но этот был так тщательно и указал, что я делаю неправильно, а также некоторые лучшие практики. Благодаря! – brucezepplin