Есть ли сценарий grep или shell, который использует регулярные выражения для изменения имен файлов? - PullRequest
1 голос
/ 31 октября 2009

Как я могу рекурсивно изменить xxx-xxx_[a-zA-Z]+_\d+_(\d+)\.jpg на $1.jpg?

Ответы [ 5 ]

2 голосов
/ 31 октября 2009
#!/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` в обратных галочках.

  • Если у вас есть тонны несвязанных файлов, вы можете добавить опцию -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
1 голос
/ 01 ноября 2009

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

1 голос
/ 31 октября 2009

Если у вас есть команда 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 \;
1 голос
/ 31 октября 2009

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

# 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 голосов
/ 31 октября 2009
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...