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

В каталоге у меня есть куча *.html файлы.

Я хотел бы переименовать их всех в *.txt

Я использую оболочку bash.

28 ответов

Решение

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


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

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

РЕДАКТИРОВАТЬ: Как указано в комментариях, это не работает для имен файлов с пробелами в них без надлежащего цитирования (теперь добавлено выше). Когда вы работаете исключительно с вашими собственными файлами, у которых, как вы знаете, нет пробелов в именах файлов, это будет работать, но всякий раз, когда вы пишете что-то, что может быть использовано позднее, не пропускайте правильное цитирование.

Если вы используете 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" "${0%.txt}.txt_bak"' {} \;

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

rename -S .html .txt *.html

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

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

На Mac...

  1. Установите переименовать, если у вас нет: brew install rename
  2. rename -S .html .txt *.html

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

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

Это самое приятное решение, которое я нашел, которое работает на 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' - '{}' \;

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

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

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

autoload -U zmv

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

Спасибо этой оригинальной статье за совет о ZMV.

В Linux или git bash окна или wsl окна попробуйте команду ниже, чтобы изменить расширение каждого файла в текущем каталоге или подкаталогах или даже их подкаталогах с помощью всего одной строки кода

      find . -depth -name "*.html" -exec sh -c 'mv "$1" "${1%.html}.txt"' _ {} \;

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

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 с регулярными выражениями, выделенными ниже:

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

Одна строка, без петель: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$ 

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

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

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

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

После сканирования чужого веб-сайта я обнаружил, что тысячи файлов не имеют расширения.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" "filename.html"

Нужно исправить, хотя: работа с пробелами в именах файлов

Переименуйте расширения файлов для всех файлов в текущем каталоге и подкаталогах без каких-либо других пакетов (используйте только сценарий оболочки):

  1. Создать сценарий оболочки rename.sh в текущем каталоге со следующим кодом:

    #!/bin/bash
    
    for file in $(find . -name "*$1"); do
      mv "$file" "${file%$1}$2"
    done
    
  2. Беги ./rename.sh .old .new.

    Например. ./rename.sh .html .txt

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

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

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

Попробуй это

rename .html .txt *.html 

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

rename [find] [replace_with] [criteria]

Подобно тому, что предлагалось ранее, я сделал это следующим образом:

find . -name '*OldText*' -exec sh -c 'mv "$0" "${0/OldText/NewText}"' {} \;

Сначала я проверил

find . -name '*OldText*' -exec sh -c 'echo mv "$0" "${0/OldText/NewText}"' {} \;

Самый простой способ - использовать rename.ul он присутствует в большинстве дистрибутивов Linux

rename.ul -o -v [oldFileExtension] [newFileExtension] [выражение для поиска файла для применения]

      rename.ul -o -v .oldext .newext *.oldext

Параметры:

-o: не перезаписывать уже существующий .newext

-v: подробный

-n: сухой прогон

Немного опоздал на вечеринку. Вы можете сделать это с помощью 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' - {}

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

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

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

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

знак равно

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

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

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

Применение:

change-ext css scss

Источник кода в функции: /questions/31221688/kak-pereimenovat-rasshirenie-dlya-paketa-fajlov/31221689#31221689

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

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

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

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

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

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

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

Вы можете использовать инструмент, предназначенный для массового переименования файлов, например renamer .

Чтобы переименовать все расширения файлов в текущей папке:

      $ renamer --find ".html" --replace ".txt" --dry-run * 

Многие другие примеры использования здесь .

Вот решение, использующее AWK. Убедитесь, что файлы находятся в рабочем каталоге. В противном случае перейдите в каталог, в котором расположены файлы html, а затем выполните следующую команду:

for i in $(ls | grep .html); do j=$(echo $i | grep -oh "^\w*." | awk '{print $1"txt"}'); mv $i $j; done

I wrote this code in my .bashrc

      alias find-ext='read -p "Path (dot for current): " p_path; read -p "Ext (unpunctured): " p_ext1; find $p_path -type f -name "*."$p_ext1'
alias rename-ext='read -p "Path (dot for current): " p_path; read -p "Ext (unpunctured): " p_ext1; read -p "Change by ext. (unpunctured): " p_ext2; echo -en "\nFound files:\n"; find $p_path -type f -name "*.$p_ext1"; find $p_path -type f -name "*.$p_ext1" -exec sh -c '\''mv "$1" "${1%.'\''$p_ext1'\''}.'\''$p_ext2'\''" '\'' _ {} \;; echo -en "\nChanged Files:\n"; find $p_path -type f -name "*.$p_ext2";'

In a folder like "/home/<user>/example-files" having this structure:

  • /home/<user>/example-files:
    • file1.txt
    • file2.txt
    • file3.pdf
    • file4.csv

The commands would behave like this:

      ~$ find-text
Path (dot for current): example-files/
Ext (unpunctured): txt

example-files/file1.txt
example-files/file2.txt


~$ rename-text
Path (dot for current): ./example-files
Ext (unpunctured): txt
Change by ext. (unpunctured): mp3

Found files:
./example-files/file1.txt
./example-files/file1.txt

Changed Files:
./example-files/file1.mp3
./example-files/file1.mp3
~$
Другие вопросы по тегам