Я скопирую мой ТАК ответ здесь:
В Ubuntu удерживаются файлы мусора ~/.local/share/Trash/files
Существует интерфейс командной строки мусора, который можно использовать. Для установки сделайте:
sudo apt-get install trash-cli
Затем для повреждения чего-то, сделайте:
trash-put myfile.txt
Следующее прямое исправление вашего подхода:
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
Однако, это очень дорого, если у вас много совпадающих файлов, потому что вы запускаете новую оболочку (которая выполняет mv
) для каждого совпадения. И если у вас есть забавные символы в любом имени файла, это взорвется. Более эффективный и безопасный подход заключается в следующем:
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
Он также имеет преимущество работы со странно названными файлами. Если найдет
, то это можно сократить до
find . -type f -name 'file*' -exec mv {} {}_renamed \;
Версия xargs
полезна, если не использовать {}
, как в
find .... -print0 | xargs --null rm
Здесь rm
вызывается один раз (или с большим количеством файлов несколько раз), но не для каждого файла.
Я удалил basename
в рассматриваемом вами файле, потому что, вероятно, это неправильно: вы бы переместили foo/bar/file8
в file8_renamed
, а не foo/bar/file8_renamed
.
Редактирование (как предложено в комментариях):
найти
без xargs
Попробовав первый ответ и немного поигравшись с ним, я обнаружил, что это можно сделать немного короче и проще, используя -execdir
:
find . -type f -name 'file*' -execdir mv {} {}_renamed ';'
Похоже, он также должен делать именно то, что вам нужно.
Я хочу расширить первый ответ и отметить, что это не сработает для добавления к имени файла с момента ./
префикс пути присутствует в аргументе имени файла.
Изменяя ответ Томаса Эркера, я считаю этот подход более общим.
find . -name PATTERN -printf "%f\0" | xargs --null -I{} mv {} "prefix {} suffix"
Параметры xargs:
- null
Указывает, что каждый аргумент, переданный через stdin
, заканчивается нулевым символом ( \ 0
). Таким образом, имя файла может содержать пробелы, в противном случае каждое слово будет обрабатываться как отдельный параметр для команды mv
.
-I replace-str
Каждое появление replace-str
будет заменено аргументом, прочитанным из stdin
. Таким образом, вы можете изменить его на другую строку, если вам это нужно.
Мне удалось сделать нечто подобное с for
, find
и mv
.
for i in $(find. -name 'config.yml'); do mv $i $i.bak; done
Это находит все файлы config.yml
и переименовывает их вconfig.yml.bak
Я подумал, что было бы неплохо, если бы здесь была возможность переименовать файл, но изменить только часть его имени. Например, расширение файла.
Какой смысл менять имя файла, если можно только добавить что-то к его имени?
find. -name "*.txt" -exec sh -c 'x={}; mv "$x" $(echo $x | sed 's/\.txt/\.bat/g')' \;