bash: как заменить рекурсивно шаблон в именах файлов из текущего каталога? [dубликат]

У меня есть много файлов с расширением .abc и вы хотите изменить их на .edefg Как это сделать из командной строки?

У меня есть корневая папка со многими подпапками, поэтому решение должен работать рекурсивно.

62
задан 29 March 2012 в 00:39

10 ответов

Портативный способ (который будет работать в любой POSIX-совместимой системе):

find /the/path -depth -name "*.abc" -exec sh -c 'mv "$1" "${1%.abc}.edefg"' _ {} \;

В bash4 вы можете использовать globstar для получения рекурсивных глобусов (**):

shopt -s globstar for file in /the/path/**/*.abc; do mv "$file" "${file%.abc}.edefg" done

Команда (perl) rename в Ubuntu может переименовывать файлы с использованием синтаксиса регулярных выражений perl, который вы можете комбинировать с globstar или find:

# Using globstar shopt -s globstar files=(/the/path/**/*.abc) # Best to process the files in chunks to avoid exceeding the maximum argument # length. 100 at a time is probably good enough. # See http://mywiki.wooledge.org/BashFAQ/095 for ((i = 0; i < ${#files[@]}; i += 100)); do rename 's/\.abc$/.edefg/' "${files[@]:i:100}" done # Using find: find /the/path -depth -name "*.abc" -exec rename 's/\.abc$/.edefg/' {} +

Также см. http: // mywiki .wooledge.org / BashFAQ / 030

72
ответ дан 17 July 2018 в 19:42

Это выполнит требуемую задачу, если все файлы находятся в одной папке

rename 's/.abc$/.edefg/' *.abc

Чтобы переименовать файлы, рекурсивно используйте это:

find /path/to/root/folder -type f -name '*.abc' -print0 | xargs -0 rename 's/.abc$/.edefg/'
37
ответ дан 17 July 2018 в 19:42

Я использовал команду mmv из пакета с таким же именем:

mmv ';*.abc' '#1#2.edefg'

; соответствует нулю или больше */ и соответствует замене #1. [F6] соответствует #2. Нерекурсивная версия будет

mmv '*.abc' '#1.edefg'
0
ответ дан 17 July 2018 в 19:42

Я нашел простой способ добиться этого. Чтобы изменить расширения многих файлов с jpg на pdf, используйте:

for file in /path/to; do mv $file $(basename -s jpg $file)pdf ; done
0
ответ дан 17 July 2018 в 19:42

Это то, что я сделал и работал довольно просто так, как я хотел. Я использовал команду mv. У меня было несколько файлов .3gp, и я хотел переименовать их все в .mp4

. Вот короткая строка для него:

for i in *.3gp; do mv -- "$i" "ren-$i.mp4"; done

Что просто просматривает текущий каталог, собирает все .3gp-файлы, а затем переименовывает (используя mv) в ren-name_of_file.mp4

0
ответ дан 17 July 2018 в 19:42

Портативный способ (который будет работать в любой POSIX-совместимой системе):

find /the/path -depth -name "*.abc" -exec sh -c 'mv "$1" "${1%.abc}.edefg"' _ {} \;

В bash4 вы можете использовать globstar для получения рекурсивных глобусов (**):

shopt -s globstar for file in /the/path/**/*.abc; do mv "$file" "${file%.abc}.edefg" done

Команда (perl) rename в Ubuntu может переименовывать файлы с использованием синтаксиса регулярных выражений perl, который вы можете комбинировать с globstar или find:

# Using globstar shopt -s globstar files=(/the/path/**/*.abc) # Best to process the files in chunks to avoid exceeding the maximum argument # length. 100 at a time is probably good enough. # See http://mywiki.wooledge.org/BashFAQ/095 for ((i = 0; i < ${#files[@]}; i += 100)); do rename 's/\.abc$/.edefg/' "${files[@]:i:100}" done # Using find: find /the/path -depth -name "*.abc" -exec rename 's/\.abc$/.edefg/' {} +

Также см. http: // mywiki .wooledge.org / BashFAQ / 030

72
ответ дан 23 July 2018 в 20:26
  • 1
    первый просто добавляет новое расширение на старое, он не заменяет ... – user2757729 21 May 2014 в 20:35
  • 2
    @ user2757729, он его заменяет. "${1%.abc}" расширяется до значения $1, за исключением без .abc в конце. См. [D0] faq 100 для получения дополнительных сведений о командах оболочки. – geirha 22 May 2014 в 13:51
  • 3
    Я запустил это в файловой структуре файлов размером ~ 70 тыс. ... по крайней мере, на моей оболочке он определенно не заменил ее. – user2757729 22 May 2014 в 20:52
  • 4
    Извините, просто настроил тестовую структуру dir и, похоже, работает. Интересно, что я вчера сделал неправильно. – user2757729 22 May 2014 в 20:56
  • 5
    @ user2757729 Вы, вероятно, покинули & quot; abc & quot; в ${1%.abc}... – kvnn 4 May 2016 в 00:47

Это выполнит требуемую задачу, если все файлы находятся в одной папке

rename 's/.abc$/.edefg/' *.abc

Чтобы переименовать файлы, рекурсивно используйте это:

find /path/to/root/folder -type f -name '*.abc' -print0 | xargs -0 rename 's/.abc$/.edefg/'
37
ответ дан 23 July 2018 в 20:26
  • 1
    Или [F1] в современную версию bash. – Adam Byrtek 19 April 2011 в 23:35
  • 2
    Большое спасибо Адаму за то, что он дал мне совет о том, как рекурсивно использовать * .abc в папках! – Rafał Cieślak 19 April 2011 в 23:42
  • 3
    Отличный совет, спасибо! Где можно найти дополнительную документацию о маленьком элементе синтаксиса регулярного выражения? Как то, что в начале s, и какие другие варианты я могу использовать там. Благодаря ! – Anto 8 March 2013 в 07:23
  • 4
    @AdamByrtek Я просто не смог с вашим предложением об Утопике. («нет таких файлов» или некоторых таких.) – Jonathan Y. 30 April 2015 в 11:25

Я использовал команду mmv из пакета с таким же именем:

mmv ';*.abc' '#1#2.edefg'

; соответствует нулю или больше */ и соответствует замене #1. [F6] соответствует #2. Нерекурсивная версия будет

mmv '*.abc' '#1.edefg'
0
ответ дан 23 July 2018 в 20:26

Я нашел простой способ добиться этого. Чтобы изменить расширения многих файлов с jpg на pdf, используйте:

for file in /path/to; do mv $file $(basename -s jpg $file)pdf ; done
0
ответ дан 23 July 2018 в 20:26

Это то, что я сделал и работал довольно просто так, как я хотел. Я использовал команду mv. У меня было несколько файлов .3gp, и я хотел переименовать их все в .mp4

. Вот короткая строка для него:

for i in *.3gp; do mv -- "$i" "ren-$i.mp4"; done

Что просто просматривает текущий каталог, собирает все .3gp-файлы, а затем переименовывает (используя mv) в ren-name_of_file.mp4

0
ответ дан 23 July 2018 в 20:26
  • 1
    Добро пожаловать в Ask Ubuntu! Хотя это ценный ответ, я рекомендую его расширить (путем редактирования), чтобы объяснить , как и почему эта команда работает. – Eliah Kagan 3 February 2013 в 22:44
  • 2
    Это переименует file.3gp в file.3gp.mp4, что может быть не то, что требуется большинству людей. – muru 14 March 2016 в 02:05
  • 3
    @muru, но принцип все еще существует. Просто выберите любое расширение , затем укажите расширение получателя, чтобы переименовать его. [F1] или .mp4 здесь были только для иллюстрации. – Rexford 15 March 2016 в 17:56
  • 4
    Синтаксис предпочтительнее, однострочный и понятный. Однако я бы использовал basename "$i" .mp4 для удаления предыдущего расширения вместо «ren- $ i.mp4». – Tao P. R. 13 May 2016 в 11:13
  • 5
    Правда. Хорошая точка зрения. – Rexford 13 May 2016 в 11:21

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

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