2009-10-31 1 views

ответ

1

См. Различные ответы на этот вопрос: SuperUser.com. Он имеет дело с той же проблемой (переименование файлов с использованием регулярного выражения). [И мне потребовались годы, чтобы найти его на StackOverflow - потому что он был не на SO, а на SU! :(]

1

Я даю вам более подробную версию, которая может обрабатывать любое имя файла (даже те, которые находятся в папках с пробельных загрязненных имен):

# file rename.sh 
old="$1" 
new="$(dirname "$1")/$(echo "$(basename "$1")"|sed 's/^xxx-xxx_[a-zA-Z]+_[0-9]+_//')" 
mv "$old" "$new" 

# execute this in the shell: 
find . -regex "xxx-xxx_[a-zA-Z]+_[0-9]+_[0-9]+\.jpg$" -exec ./rename.sh "{}" ";" 
+0

Это совпадает с именем файла, такие как: ххх-xxx_ERR_19_01.jpg и возвращает 01 Что мне делать с этим кодом – steven

+0

, и я не думаю, что это то, что мне нужно: у меня есть 1/ххх-xxx_ERR_19_01.jpg 2/ххх-xxx_ERR_19_01.jpg 3/ххх-xxx_ERR_19_01.jpg – steven

+0

Ах, я забыл о поддиректорий в команде, исправит ... – soulmerge

2
#!/bin/bash 

find . | while read OLD; do 
    NEW="`sed -E 's/(.*\/)?xxx-xxx_[a-zA-Z]+_[0-9]+_([0-9]+)\.jpg/\1\2.jpg/' <<< "$OLD"`" 
    [ "$OLD" != "$NEW" ] && mv "$OLD" "$NEW" 
done 

Некоторые замечания по этому вопросу:

  • конвейера от find к while read петле аккуратным способ чтения выхода find по одной строке за раз. Это хорошо, потому что он будет обрабатывать файлы, так как find находит их, не создавая сначала весь список файлов, как это было бы, если бы вы делали `find` в backticks.

  • Если у вас есть тонны несвязанных файлов, вы можете добавить опцию -regex в find в ответ на вопрос soulmerge, но если нет, не нужно.

  • Я изменил ваше регулярное выражение, чтобы разрешить имена каталогов спереди. Они будут захвачены в \1, и номер, который вы ищете, будет \2.

  • sed <<< "$OLD" это то же самое, как echo "$OLD" | sed, только немного любитель ...

  • [ "$OLD" != "$NEW" ] && mv это то же самое, как if [ "$OLD" != "$NEW" ]; then mv; fi, только немного охотницы ...

Редактировать : Изменено \d до [0-9] для совместимости. Я тестировал его на своем Mac, и он работает. Вот что произошло в тестовом каталоге я создал:

mv ./1/xxx-xxx_ERR_19_02.jpg ./1/02.jpg 
mv ./2/xxx-xxx_BLAH_266_14.jpg ./2/14.jpg 
mv ./xxx-xxx_ERR_19_01.jpg ./01.jpg 
+0

Как это использовать? – steven

+0

и я не думаю, что это работает для подкаталогов? – steven

+0

'find' является рекурсивным, поэтому он должен! –

0
find /path -type f -name "???-???_[a-zA-Z]*_[0-9]*_*.???" | while read FILE 
do 
    f=${FILE%%.???} 
    number=${f##*_} 
    extension=${FILE##*.} 
    path=${FILE%/*} 
    echo "mv '$FILE' '$path/$number.$extension" 
done 
1

Если у вас есть rename (или prename) команда (это скрипт на Perl, который иногда поставляется с Perl):

find -type d -name dir -exec rename 's/xxx-xxx_[a-zA-Z]+_\d+_(\d+)\.jpg/$1.jpg/' {}/xxx-xxx_[a-zA-Z]*[0-9].jpg \; 
+0

Что такое переименование? Я не понимаю, для чего это 's'? – steven

+0

Не работал. – steven

+0

's /.../.../' - команда Perl (и 'sed'). Он ищет регулярное выражение между первой и второй косой чертой и заменяет его тем, что находится между второй и третьей косой чертой. «$ 1» является обратной ссылкой на часть регулярного выражения, которое находится в круглых скобках ('sed' использует' \ 1'). –

Смежные вопросы