Как переименовать расширение для группы файлов?

В каталоге у меня есть куча *.html файлов. Я хотел бы переименовать их всех в *.txt

Как я могу это сделать? Я использую оболочку bash.

Ответ 1

Для лучшего решения (только с функцией bash, в отличие от внешних вызовов) см. один из других ответов.


Следующее будет делать и не требует, чтобы система имела программу rename (хотя вы чаще всего это имели бы в системе):

for file in *.html; do
    mv "$file" "$(basename "$file" .html).txt"
done

EDIT: как указано в комментариях, это не работает для имен файлов с пробелами в них без правильного цитирования (теперь добавлено выше). При работе исключительно с вашими собственными файлами, которые, как вы знаете, не имеют пробелов в именах файлов, это будет работать, но всякий раз, когда вы пишете что-то, что может быть повторно использовано позднее, не пропустите правильное цитирование.

Ответ 2

Если вы используете bash, вам не нужны внешние команды, такие как sed, basename, rename, expr и т.д.

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done

Ответ 3

rename 's/\.html$/\.txt/' *.html

делает именно то, что вы хотите.

Ответ 4

Это работало для меня на OSX с .txt на .txt_bak

find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;

Ответ 5

Вы хотите использовать rename:

rename -S .html .txt *.html

Это делает именно то, что вы хотите - оно изменит расширение от .html до .txt для всех файлов, соответствующих *.html.

Примечание: Greg Hewgill правильно указывает, что это не встроенный bash; и представляет собой отдельную команду Linux. Если вам просто нужно что-то в Linux, это должно работать нормально; если вам нужно что-то более кросс-платформенное, тогда взгляните на один из других ответов.

Ответ 6

На Mac...

  • Установите rename, если вы этого не сделали: brew install rename
  • rename -S .html .txt *.html

Ответ 7

Для пользователей Ubuntu:

rename 's/\.html$/\.txt/' *.html

Ответ 8

Это самое приятное решение, которое я нашел, которое работает на OSX и Linux, и оно прекрасно работает и с git!

find. -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".tsx' - '{}' \;

и с мерзавцем:

find. -name "*.js" -exec bash -c 'git mv "$1" "${1%.js}".tsx' - '{}' \;

Ответ 9

Вот пример команды rename:

rename -n ’s/\.htm$/\.html/’ *.htm

-n означает, что это пробный прогон и фактически не изменит никаких файлов. Он покажет вам список файлов, которые будут переименованы, если вы удалите -n. В приведенном выше случае он преобразует все файлы в текущую директорию из расширения файла .htm в .html.

Если результат вышеуказанного тестового прогона выглядел нормально, вы можете запустить финальную версию:

rename -v ’s/\.htm$/\.html/’ *.htm

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

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html

Сложная часть в середине - это подстановка Perl с регулярными выражениями, выделенная ниже:

rename -v ’s/\.htm$/\.html/’ *.htm

Ответ 10

После того, как кто-то еще сканирует сайт, я столкнулся с тысячами файлов, у которых отсутствует расширение .html, через широкое дерево подкаталогов.

Чтобы переименовать их все за один снимок, кроме файлов, уже имеющих расширение .html(большинство из них вообще не было), это сработало для меня:

cd wwwroot
find . -xtype f \! -iname *.html   -exec mv -iv "{}"  "{}.html"  \;  # batch rename files to append .html suffix IF MISSING

В случае OP я мог немного изменить это, чтобы переименовать *.txt файлы, например:

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 

Сломанная вниз (hammertime!):

-iname *.txt
- Средство рассматривает ТОЛЬКО файлы, уже заканчивающиеся на .txt

mv -iv "{}. {txt, html}" - Когда find передает {} в качестве имени файла, ${filename%. *} Извлекает свое базовое имя без какого-либо расширения для формирования параметров mv. bash переносит {txt, html}, чтобы переписать его как два параметра, так что последняя команда запускается как: mv -iv "filename.txt" "filename.html"

Требуется исправление: обработка пробелов в именах файлов

Ответ 11

В этом вопросе явно упоминается Bash, но если у вас есть ZSH, это довольно просто:

zmv '(*).*' '$1.txt'

Если вы получили zsh: command not found: zmv просто запустите:

autoload -U zmv

А потом попробуйте еще раз.

Благодаря этой оригинальной статье за отзыв о ZMV.

Ответ 12

команда mmv, похоже, делает эту задачу очень эффективно на огромное количество файлов (десятки тысяч в секунду). Например, чтобы переименовать все файлы .xml в файлы .html, используйте это:

mmv ";*.xml" "#1#2.html"

; будет соответствовать пути, * будет соответствовать имени файла, и они называются #1 и #2 в имени замены.

Ответы, основанные на exec, или каналы были либо слишком медленными, либо неудачными в очень большом количестве файлов.

Ответ 13

Попробуйте это

rename .html .txt *.html 

использование:

rename [find] [replace_with] [criteria]

Ответ 14

Немного поздно на вечеринку. Вы можете сделать это с помощью xargs:

ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}

Или, если все ваши файлы находятся в папке

ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}

Ответ 15

Если вы предпочитаете PERL, есть короткий PERL script (или написанный Ларри Уолл, создатель PERL), который будет делать именно то, что вы хотите здесь: tips.webdesign10.com/files/rename.pl.txt. Для вашего примера следующее должно сделать трюк

rename.pl 's/html/txt/' *.html

=)

(Спасибо @loretoparisi за обновленный URL)

Ответ 16

Это хороший способ изменить несколько расширений одновременно:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

Примечание: будьте осторожны, чтобы размер расширения был одинаковым (???)

Ответ 17

К сожалению, это не тривиально делать портативно. Вам, вероятно, понадобится немного волшебства expr.

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

Удалите эхо, как только вы счастливы, он делает то, что вы хотите.

Изменить: basename, вероятно, немного читаем для этого конкретного случая, хотя expr является более гибким в целом.

Ответ 18

Красиво и просто!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;

Ответ 19

Вот что я использовал, чтобы переименовать .edge файлы .blade.php

for file in *.edge; do     mv "$file" "$(basename "$file" .edge).blade.php"; done

Работает как шарм.

Ответ 20

Одна строка без петель: ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {} ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}

[email protected]:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
[email protected]:~/pgsql$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
[email protected]:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt
[email protected]:~/pgsql$ 

Ответ 21

Вы также можете создать функцию в Bash, добавить ее в .bashrc или что-то еще, а затем использовать в любом месте.

change-ext() {
    for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}

Использование:

change-ext css scss

Источник кода в функции: fooobar.com/info/924/...