Как переименовать расширение для группы файлов?
-
22-07-2019 - |
Вопрос
В каталоге у меня есть куча файлов *. html
. Я хотел бы переименовать их всех в *. Txt
Как я могу это сделать? Я использую оболочку bash.
Решение
Для лучшего решения (с использованием только функций bash, в отличие от внешних вызовов) см. один из других ответов .
<Ч> Следующие действия могут привести к тому, что в системе не будет программы rename
(хотя это чаще всего встречается в системе):
for file in *.html; do
mv "$file" "$(basename "$file" .html).txt"
done
EDIT: Как указано в комментариях, это не работает для имен файлов с пробелами в них без правильных кавычек (теперь добавлено выше). Когда вы работаете исключительно с вашими собственными файлами, у которых, как вы знаете, нет пробелов в именах файлов, это будет работать, но всякий раз, когда вы пишете что-то, что может быть использовано позже, не пропускайте правильное цитирование. Р>
Другие советы
Если вы используете bash, вам не нужны внешние команды, такие как sed, basename, rename, expr и т. д.
for file in *.html
do
mv "$file" "${file%.html}.txt"
done
rename 's/\.html$/\.txt/' *.html
делает именно то, что вы хотите.
Это работало для меня в OSX с .txt до .txt_bak
find . -name '*.txt' -exec sh -c 'mv "<*>" "${0%.txt}.txt_bak"' {} \;
Вы хотите использовать rename
:
rename -S .html .txt *.html
Это именно то, что вы хотите - оно изменит расширение с .html
на .txt
для всех файлов, соответствующих *. html
. р>
Примечание: Грег Хьюгилл правильно указывает, что это не встроенная функция bash; и это отдельная команда Linux. Если вам просто нужно что-то в Linux, это должно работать нормально; если вам нужно что-то более кроссплатформенное, взгляните на один из других ответов.
На Mac ...
<Ол> brew install rename
переименовать -S .html .txt * .html
Для пользователей Ubuntu:
rename 's/\.html$/\.txt/' *.html
Вот пример команды переименования:
rename -n ’s/\.htm$/\.html/’ *.htm
-n означает, что это тестовый запуск, и он не будет изменять никакие файлы. Он покажет вам список файлов, которые будут переименованы, если вы удалите -n. В приведенном выше случае он преобразует все файлы в текущем каталоге с расширением .htm в .html.
Если результаты вышеприведенного теста выглядят нормально, вы можете запустить финальную версию:
rename -v ’s/\.htm$/\.html/’ *.htm
Опция -v является необязательной, но рекомендуется включить ее, поскольку она является единственной записью изменений, которые были внесены с помощью команды переименования, как показано в примере выходных данных ниже:
$ 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 с регулярными выражениями, выделенными ниже:
<*>После сканирования чужого веб-сайта я обнаружил, что тысячи файлов не имеют расширения .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} \;
Разбитый (время молотка!):
-iname * .txt
- Это означает, что ТОЛЬКО файлы, заканчивающиеся на .txt
mv -iv " {}. {txt, html} "
- Когда find передает {} в качестве имени файла, $ {filename%. *} Извлекает его базовое имя без какого-либо расширения, чтобы сформировать параметры для mv . bash использует {txt, html}, чтобы переписать его как два параметра, поэтому последняя команда выполняется так: Исправление необходимо, хотя: работа с пробелами в именах файлов mv -iv " filename.txt " & Quot; filename.html & Quot; код> р>
В этом вопросе явно упоминается Bash, но если у вас есть ZSH, это довольно просто:
zmv '(*).*' '$1.txt'
Если вы получили команду zsh: not found: zmv
, просто запустите:
autoload -U zmv
А затем попробуйте еще раз.
Благодаря этой оригинальной статье за подсказку о змв.
Это самое приятное решение, которое я нашел, которое работает на OSX и Linux, и оно прекрасно работает и с git!
найти. -имя " *. js " -exec bash -c 'mv " $ 1 " " $ {1% .js} " .tsx '-' {} '\;
и с помощью git:
найти. -имя " *. js " -exec bash -c 'git mv " $ 1 " " $ {1% .js} " .tsx '-' {} '\;
команда mmv
, кажется, выполняет эту задачу очень эффективно на огромное количество файлов (десятки тысяч в секунду). Например, чтобы переименовать все файлы .xml
в файлы .html
, используйте это:
mmv ";*.xml" "#1#2.html"
;
будет соответствовать пути, *
будет соответствовать имени файла, и они называются # 1
и # 2
в имени замены. Р>
Ответы, основанные на exec
или каналах, были либо слишком медленными, либо терпели неудачу на очень большом количестве файлов. Р>
Попробуйте это
rename .html .txt *.html
использование:
rename [find] [replace_with] [criteria]
Немного опоздал на вечеринку. Вы можете сделать это с помощью 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' - {}
Если вы предпочитаете PERL, существует короткий сценарий PERL (изначально написанный Ларри Уоллом, создателем PERL), который будет делать именно то, что вы хотите: tips.webdesign10.com/files/rename.pl.txt . Для вашего примера следующее должно помочь
rename.pl 's / html / txt /' * .html
=)
(спасибо @loretoparisi за обновленный URL)
К сожалению, это не тривиально делать переносимо. Вам, вероятно, нужно немного магии опыта.
for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done
Уберите эхо, как только вы будете довольны, он сделает то, что вы хотите.
Edit: basename
, вероятно, немного более читабелен для этого конкретного случая, хотя expr
в целом более гибкий.
Это хороший способ изменить несколько расширений одновременно:
for fname in *.{mp4,avi}
do
mv -v "$fname" "${fname%.???}.mkv"
done
Примечание: будьте осторожны, чтобы размер расширения был одинаковым (???)
Приятно & amp; просто! Р>
find . -iname *.html -exec mv {} "$(basename {} .html).text" \;
Вот что я использовал для переименования файлов .edge
в .blade.php
for file in *.edge; do mv "$file" "$(basename "$file" .edge).blade.php"; done
Работает как шарм.
Одна строка, без петель:
ls -1 | xargs -L 1 -I {} bash -c 'mv $ 1 " $ {1%. *}. txt "' _ {}
cbongiorno@ip-172-31-26-242:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json ac8453e2-0d82-4d43-b80e-205edb754700.json
cbongiorno@ip-172-31-26-242:~/pgsql$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
cbongiorno@ip-172-31-26-242:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt ac8453e2-0d82-4d43-b80e-205edb754700.txt
cbongiorno@ip-172-31-26-242:~/pgsql$