пакетное переименование для изменения только одного символа - PullRequest
3 голосов
/ 11 мая 2009

Как переименовать все файлы в одном каталоге в новое имя с помощью команды mv. В каталоге имеется 1000 файлов, и требуется изменить последний символ имени каждого файла на определенный символ. Пример: файлы

abc.txt
asdf.txt
zxc.txt
...
ab_.txt
asd.txt

должно измениться на

ab_.txt
asd_.txt
zx_.txt
...
ab_.txt
as_.txt

Ответы [ 7 ]

2 голосов
/ 11 мая 2009

Вы должны следить за конфликтами имен, но это должно сработать:

for i in *.txt ; do
    j=$(echo "$i" | sed 's/..txt$/_.txt/')
    echo mv \"$i\" \"$j\"
    #mv "$i" "$j"
done

после того, как вы раскомментировали mv (я оставил комментарий, чтобы вы могли видеть, что он делает безопасно). Цитаты предназначены для обработки файлов с пробелами (на мой взгляд, злые, мерзкие вещи: -).

2 голосов
/ 11 мая 2009

Если все файлы заканчиваются на ".txt", вы можете использовать для этого mmv (Multiple Move):

mmv "*[a-z].txt" "#1_.txt"

Plus: mmv сообщит вам, когда возникнет коллизия (в вашем примере: abc.txt становится ab_.txt, который уже существует) до любого файла, который будет переименован.

Обратите внимание, что вы должны заключать в кавычки имена файлов, иначе оболочка расширит список до того, как mmv увидит его (но mmv обычно тоже поймает эту ошибку).

1 голос
/ 11 мая 2009

Это определенное требование, что вы используете команду mv?
Утилита perl rename была написана для такого рода вещей. Это стандарт для дистрибутивов Linux на основе Debian, но, согласно этой странице , его очень легко добавить к любому другому.

Если он уже есть (или если вы его установили), вы можете сделать:

rename -v 's/.\.txt$/_\.txt/' *.txt

На странице, приведенной выше, есть некоторая базовая информация о регулярных выражениях и, если нужно, вещи.

1 голос
/ 11 мая 2009

Поиск должен быть более эффективным, чем for file in *.txt, который расширяет все ваши 1000 файлов в длинный список параметров командной строки. Пример (обновлен для использования подхода замены bash):

find . \( -type d ! -name . -prune \) -o \( -name "*.txt" \) | while read file
do 
    mv $file ${file%%?.txt}_.txt
done
0 голосов
/ 11 мая 2009

Вы можете использовать оператор bash ${parameter%%word} следующим образом:

for FILE in *.txt; do
   mv $FILE ${FILE%%?.txt}_.txt
done
0 голосов
/ 11 мая 2009

Если все ваши файлы имеют суффикс .txt, я предлагаю следующий скрипт:

for i in *.txt
do
    r=`basename $i .txt | sed 's/.$//'`
    mv $i ${r}_.txt
done
0 голосов
/ 11 мая 2009

Я не уверен, будет ли это работать с тысячами файлов, но в bash:

for i in *.txt; do
   j=`echo $i |sed 's/.\.txt/_.txt/'`
   mv $i $j
done
...