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

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

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

Например, я просто не могу сказать 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

6
задан 13 April 2017 в 05:24

4 ответа

find . -name '*.txt' -print0 | xargs -0 -n1 bash -c 'mv "$0" "${0/oldname/newname}"'

Очевидно, это переименовывает шаблон, просто простой пример, но остерегайтесь этого, как это, отредактирует целый путь, не только имя файла.

7
ответ дан 23 November 2019 в 07:29

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

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

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

При необходимости в более сложных примерах необходимо изучить страницу справочника.

3
ответ дан 23 November 2019 в 07:29

Вы могли исследовать изобилие доступного выбора:

`$ apt-cache search rename | grep -i rename` 
0
ответ дан 23 November 2019 в 07:29

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

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

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. переименовывает, использует регулярное выражение Perl для переименования каждого файла.
  • Обратные косые черты после -type и -name символ продолжения строки удара. Я использую их для создания этого примера более читаемым, но они не нужны на практике.
  • Однако обратная косая черта в конце -execdir строка требуется. Это там, чтобы выйти из точки с запятой, которая завершает команду, выполненную -execdir. Забава!

Объяснение regex:

  • s/ запустите regex
  • \.\/ соответствуйте продвижению./это передачи-execdir в. Используйте \для выхода. и / метасимволы
  • (.+) соответствуйте запуску имени файла. Круглые скобки получают соответствие для более позднего использования
  • _one\.txt соответствуйте "_one.txt", выйдите из точечного метасимвола
  • $ привяжите соответствие в конце строки
  • / отмечает конец части "соответствия" regex и запуска части "замены"
  • $1 ссылается на существующее имя файла, потому что мы получили его с круглыми скобками. При использовании нескольких наборов круглых скобок в части "соответствия" можно отослать к ним сюда использование 2$, 3$, и т.д.
  • _two.txt новое имя файла закончится в "_two.txt". Никакая потребность выйти из точечного метасимвола здесь в разделе "замены"
  • / конец regex

Прежде

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
ответ дан 23 November 2019 в 07:29

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

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