bash скрипт для переименования всех файлов в каталоге? - PullRequest
4 голосов
/ 24 декабря 2009

У меня есть куча файлов, которые нужно переименовать.

file1.txt needs to be renamed to file1_file1.txt
file2.avi needs to be renamed to file2_file2.avi

как видите, мне нужно _, следуя оригинальному имени файла.

Есть много этих файлов.

Ответы [ 8 ]

5 голосов
/ 24 декабря 2009

Пока что все ответы даны либо:

  1. Требуется какой-нибудь непереносимый инструмент
  2. Жутко порвать с именами файлов, содержащими пробелы или переводы строк
  3. Не является рекурсивным, т.е. не спускается в подкаталоги

Эти два сценария решают все эти проблемы.

Bash 2.X / 3.X

#!/bin/bash

while IFS= read -r -d $'\0' file; do
    dirname="${file%/*}/"
    basename="${file:${#dirname}}"
    echo mv "$file" "$dirname${basename%.*}_$basename"
done < <(find . -type f -print0)

Bash 4.X

#!/bin/bash

shopt -s globstar
for file in ./**; do 
    if [[ -f "$file" ]]; then
        dirname="${file%/*}/"
        basename="${file:${#dirname}}"
        echo mv "$file" "$dirname${basename%.*}_$basename"
    fi
done

Обязательно удалите echo из любого сценария, который вы выберете, как только вы будете удовлетворены его выводом, и запустите его снова

Редактировать

Исправлена ​​проблема в предыдущей версии, которая неправильно обрабатывает имена путей.

4 голосов
/ 24 декабря 2009

Для вашего конкретного случая вы хотите использовать mmv следующим образом:

pax> ll
total 0
drwxr-xr-x+ 2 allachan None 0 Dec 24 09:47 .
drwxrwxrwx+ 5 allachan None 0 Dec 24 09:39 ..
-rw-r--r--  1 allachan None 0 Dec 24 09:39 file1.txt
-rw-r--r--  1 allachan None 0 Dec 24 09:39 file2.avi

pax> mmv '*.*' '#1_#1.#2'

pax> ll
total 0
drwxr-xr-x+ 2 allachan None 0 Dec 24 09:47 .
drwxrwxrwx+ 5 allachan None 0 Dec 24 09:39 ..
-rw-r--r--  1 allachan None 0 Dec 24 09:39 file1_file1.txt
-rw-r--r--  1 allachan None 0 Dec 24 09:39 file2_file2.avi

Вы должны знать, что сопоставление с подстановочными знаками не является жадным. Это означает, что файл a.b.txt будет преобразован в a_a.b.txt, а не a.b_a.b.txt.

Программа mmv была установлена ​​как часть моего CygWin, но мне пришлось

sudo apt-get install mmv

на моей коробке с Ubuntu, чтобы получить его. Если он не входит в стандартный дистрибутив, надеюсь, какой бы менеджер пакетов вы ни использовали, он будет доступен.

Если по какой-то причине вам не разрешено устанавливать его, вам придется использовать одно из других решений типа bash for -loop, показанных в других ответах. Я сам предпочитаю краткость mmv, но у вас может не быть выбора.

4 голосов
/ 24 декабря 2009
for file in file*.*
do 
    [ -f "$file" ] && echo mv "$file" "${file%%.*}_$file"
done

Идея для рекурсии

recurse() {
 for file in "$1"/*;do
    if [ -d "$file" ];then
        recurse "$file"
    else
        # check for relevant files
        # echo mv "$file" "${file%%.*}_$file"
    fi
 done
}
recurse /path/to/files
2 голосов
/ 24 декабря 2009
find . -type f | while read FN; do
  BFN=$(basename "$FN")
  NFN=${BFN%.*}_${BFN}
  echo "$BFN -> $NFN"
  mv "$FN" "$NFN"
done
0 голосов
/ 24 декабря 2009

Я использую prename (на основе Perl), который включен в различные дистрибутивы Linux. Он работает с регулярными выражениями, так сказать, измените все img_x.jpg на IMAGE_x.jpg, которые вы бы сделали

prename 's/img_/IMAGE_/' img*jpg

Вы можете использовать флаг -n для предварительного просмотра изменений без внесения каких-либо реальных изменений.

prename man entry

0 голосов
/ 24 декабря 2009

Следует упомянуть инструмент mmv, специально разработанный для этого.

Это описано здесь: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/mass-rename.html

... вместе с альтернативами.

0 голосов
/ 24 декабря 2009
#!/bin/bash
# Don't do this like I did:
# files=`ls ${1}`

for file in *.*
do
if [ -f $file ];
then
newname=${file%%.*}_${file}
mv $file $newname
fi
done

Этот не будет переименовывать подкаталоги, только обычные файлы.

0 голосов
/ 24 декабря 2009

Мне нравится сценарий переименования поваренной книги PERL для этого. Это может быть не / bin / sh, но вы можете делать регулярные выражения, как переименования.

Метод / bin / sh будет использовать sed / cut / awk для изменения каждого имени файла внутри цикла for. Если каталог большой, вам нужно использовать xargs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...