开发者

Is there a grep or shell script that uses a regex to change filenames?

How can I recursively change xxx-xx开发者_Go百科x_[a-zA-Z]+_\d+_(\d+)\.jpg into $1.jpg?


#!/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

Some notes on this:

  • Piping the output of find to a while read loop is a neat way of reading the output of find one line at a time. It's nice because it'll process the files as find finds them without having to build up the whole list of files first, as would happen if you did `find` in backticks.

  • If you have tons of unrelated files then you can add the -regex option to find as per soulmerge's answer, but if not eh, no need.

  • I modified your regex to allow for directory names at the front. They'll get captured in \1 and the number you're looking for will be \2.

  • sed <<< "$OLD" is the same thing as echo "$OLD" | sed, just a little fancier...

  • [ "$OLD" != "$NEW" ] && mv is the same thing as if [ "$OLD" != "$NEW" ]; then mv; fi, just a little fancier...

Edit: Changed \d to [0-9] for compatibility. I tested it on my Mac and it works. Here's what happened in a test directory I set up:

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


See the various answers to this question on SuperUser.com. It is dealing with the same issue (renaming files using a regex). [And it took me ages to find it on StackOverflow - because it wasn't on SO but on SU! :( ]


I am giving you the more verbose version that can handle any file name (even those that are in folders with white-space contaminated names):

# 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 "{}" ";"


If you have the rename (or prename) command (it's a Perl script that sometimes comes with 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 \;


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜