Рекурсивно переименовывать файлы - oneliner предпочтительно [дублировать]

У этого вопроса уже есть ответ здесь: Как изменить расширение нескольких файлов из командной строки? 8 ответов

Я нашел этот ответ, как я ... но он просто не работает - он не переименовал какой-либо файл для неизвестного мне причины

Прежде чем я начал искать вокруг я думал, что это должно быть легкой задачей даже для начинающего пингвина, но для меня это не кажется.

Например, я просто не могу сказать ls перечислить все *.txt в все вложенные папки, которые были для меня неожиданностью (без grep или подобных). Затем я обнаружил, что find и find . -name name_1.txt перечислены файлы в порядке, но

for f in $(find . -name name_1.txt) ; do echo "$f" ; done

разделяет целые пути файла с пространством как разделителем, поэтому непригодно передавать этот вывод некоторым команда, подобная mv или rename

Я хочу спросить, что случилось с командой выше, и, если возможно, какой-нибудь изящный oneliner, чтобы я мог рекурсивно переименовать name_1.txt в name_2.txt

1
задан 13 April 2017 в 15:24

3 ответа

команда mmv сделает это в довольно простом вызове:

mmv "; name_1.txt" "# 1name_2.txt"

";" подстановочный знак, который повторно используется в заменяемом имени файла как «# 1», также совпадает с подкаталогами.

Если вам нужны более сложные примеры, вы должны изучить man-страницу.

2
ответ дан 25 May 2018 в 16:44
  • 1
    Спасибо, но я не пробовал, так как на данный момент он не установлен на моем 11.04, и первый ответ работал нормально. ура – zetah 18 November 2011 в 19:17

Как указывает @ams, многие рекурсивные решения для замены требуют, чтобы вы работали со всем путем, а не только с именем файла.

Я использую действие find -execdir для решения этой проблемы , Если вы используете -execdir вместо -exec, указанная команда запускается из подкаталога, содержащего сопоставленный файл. Таким образом, вместо передачи всего пути к rename он пропускает только ./filename. Это значительно упрощает запись команды replace.

find /the/path -type f \
               -name '*_one.txt' \
               -execdir rename 's/\.\/(.+)_one\.txt$/$1_two.txt/' {} \;

Подробнее:

-type f означает, что поиск файлов, а не каталогов -name '*_one.txt' означает означает только совпадение имен файлов это конец в _one.txt В этом ответе я использую команду rename вместо mv. rename использует регулярное выражение Perl для переименования каждого файла. Обратные косые черты после -type и -name являются символами продолжения строки bash. Я использую их, чтобы сделать этот пример более читабельным, но на практике они не нужны. Однако обратная косая черта в конце строки -execdir требуется. Здесь есть esacpe точка с запятой, которая завершает команду, выполняемую -execdir. Весело!

Объяснение регулярного выражения:

-type f означает только поиск файлов, а не каталогов \.\/, совпадающих с ведущим ./, который -execdir проходит в Используйте \, чтобы избежать. и / metacharacters -name '*_one.txt' означает означает только совпадение имен файлов, заканчивающихся в _one.txt _one\.txt, совпадение «_one.txt», выход из метасимвола точки . В этом ответе я использую rename вместо mv. rename использует регулярное выражение Perl для переименования каждого файла. / отмечает конец части «соответствия» регулярного выражения и начало части «заменить» . Обратные косые черты после -type и -name - символ продолжения строки bash. Я использую их, чтобы сделать этот пример более читабельным, но на практике они не нужны. _two.txt имя нового файла закончится в «_two.txt». Не нужно избегать метасимвола точки здесь, в разделе «замена» Однако обратная косая черта в конце строки -execdir требуется. Здесь есть esacpe точка с запятой, которая завершает команду, выполняемую -execdir. Fun!

До

tree --charset=ascii

|-- a_one.txt
|-- b_one.txt
|-- Not_this.txt
`-- dir1
    `-- c_one.txt

После

tree --charset=ascii

|-- a_two.txt
|-- b_two.txt
|-- Not_this.txt
`-- dir1
    `-- c_two.txt

Подсказка: rename - n. Он выполняет сухой запуск и показывает вам, какие имена он изменит, но не вносит никаких изменений.

1
ответ дан 25 May 2018 в 16:44

Вы можете изучить множество доступных вариантов:

`$ apt-cache search rename | grep -i rename` 
0
ответ дан 25 May 2018 в 16:44

Другие вопросы по тегам:

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