Добавить к имени файла с помощью команды find

. * соответствует все в остальной части строки, поэтому все заменено. Если вы хотите заменить все до следующего пробела, вам понадобится [^] вместо .`

5
12.04.2017, 20:52
5 ответов

Как насчет

find . -name '201*' -execdir basename {} \; | xargs -I{} mv {} foo_{}

базовое имя предоставляется coreutils , а поскольку xargs предоставляется findutils он должен быть не менее переносимым, чем сам find -execdir .


В качестве альтернативы, использование только функций оболочки POSIX

find . -name '201*' -execdir sh -c 'mv "$1" "foo_${1#*/}"' sh {} \;
2
27.01.2020, 20:38

Нет. Но команда rename предлагает простое решение.

$ ls -1
201a.txt
201b.png
$ rename 201 foo_201 201*
$ ls -1
foo_201a.txt
foo_201b.png
$
2
27.01.2020, 20:38

Вместо этого можно использовать звездочку (*), которая удаляет часть ./:

find * -name '201*' -exec mv {} foo_{} \;  
0
27.01.2020, 20:38

В GNU Parallel это выглядит так:

# Make an annoying dir and a couple of annoying files
mkdir '"*'"  '"
touch '"*'"  '"/201'"*'"  '".txt
touch '"*'"  '"/201'"*'"  '".png

# GNU Parallel deals nicely with annoying files
find . -name '201*' | parallel mv {} {//}/foo_{/}
1
27.01.2020, 20:38

Это невозможно только с find, даже с GNU find. GNU find может печатать файлы с удаленным префиксом командной строки и добавленным вместо него другим префиксом, используя -printf foo_%p вместо -print, но нет ничего подобного для - исполнить.

(Вы можете использовать find -printf 'mv foo_%p …' | sh, если вам нравится жить опасно. Это работает только с «ручными» именами файлов и ужасно ломается, если есть пробелы, кавычки и другие специальные символы в именах файлов. Так что не делайте этого.)

Стандартный способ сделать это (работающий в любой системе POSIX, а также общепринятый способ) — вызвать shell для выполнения манипуляций со строками.

find . -name '201*' -exec sh -c 'mv -- "$0" "${0%/*}/foo_${0##*/}"' {} \;

Я не использую -execdir, потому что это расширение GNU, а вы просили о переносимости. Обратите внимание, что {} передается оболочке в качестве аргумента.Никогда не используйте {} внутри шелл-кода: не только потому, что он не переносим, ​​но и, что наиболее важно, потому что это приведет к тому, что имя файла будет интерпретировано как шелл-код, что не удастся, если имя файла содержит специальные символы. .

В современных системах POSIX (всех, выпущенных в последнее десятилетие) вы можете немного ускорить эту команду, группируя вызовы оболочки.

find . -name '201*' -exec sh -c 'for x do mv -- "$x" "${x%/*}/foo_${x##*/}"; done' sh {} +

Кроме того, в ksh, bash или zsh вместо вызова find можно использовать рекурсивную подстановку.

set -o globstar # ksh only
shopt -s globstar # bash only
for x in **/201*; do
  mv -- "$x" "${x%/*}/foo_${x##*/}"
done
2
27.01.2020, 20:38

Теги

Похожие вопросы