2

У меня есть несколько файлов, таких как (в Mac OS X):

product-103-footer.tpl
product-103-header.tpl
product-103.tpl

Я хочу заменить «103» во всех именах файлов чем-то другим, используя grep и sed, или что-то в этом роде.

Как мне это сделать?

Вот некоторая псевдо-командная строка того, чего я хочу достичь

find . /[103] | grep 103 | sed s/103/104/

Надеюсь, что это имеет смысл!

РЕДАКТИРОВАТЬ:

Становиться ближе:

find . -name 'product-103*' -print | sed 's/103/104/g'

3 ответа3

9

Вы можете использовать опцию find exec чтобы (рекурсивно) зациклить все файлы, а затем использовать простые замены строк:

find . -type f -name "product-103*" \
-exec sh -c 'echo mv "$0" "${0/103/104}"' '{}' \;

Удалите echo когда вы уверены, что это делает то, что вы хотите.

По сути, exec заменяет имя каждого файла, найденного в {} , которое передается в качестве аргумента sh -c . Этот аргумент доступен как $0 , таким образом, имя файла. Мы используем этот аргумент $0 в вызове mv , где вторым аргументом является новое имя файла. Здесь 103 заменяется на 104. Обратите внимание, что двойные кавычки необходимы для правильной обработки пробелов в именах файлов.

См. Управление строками в Руководстве по написанию сценариев Bash.


С zmv zsh (на OS X через /bin/zsh):

autoload -U zmv
zmv -Wn '*103*' '*104*'

Удалите опцию -n когда это сделает то, что вам нужно.

2

Perl лучше для этого.

find . -name 'product-103*' | perl -nle '($new=$_) =~ s/103/104/;rename $_,$new'

Следующий кусок кода

perl -nle '($new=$_) =~ s/103/104/;rename $_,$new'

в конечном итоге будет расширен до

while (<>) {
    chomp;
    ($new=$_) =~ s/103/104/;
    rename $_, $new;
}

Оператор <> получает каждое имя файла с символом «\n» в конце и сохраняет его в $ _, затем chomp отключает «\n». Затем переменная $new получает старое имя файла от $_ и заменяет 103 на 104. Наконец, rename просто переименуйте файл в новое имя. Для получения более подробной информации о -n -l -e переключателе, обратитесь к PerlRun части perldoc.

2
for f in product-103*; do mv "$f" "${f/103/104}"; done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .