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
findto awhile readloop is a neat way of reading the output offindone line at a time. It's nice because it'll process the files asfindfinds 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
-regexoption tofindas 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
\1and the number you're looking for will be\2.sed <<< "$OLD"is the same thing asecho "$OLD" | sed, just a little fancier...[ "$OLD" != "$NEW" ] && mvis the same thing asif [ "$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
加载中,请稍侯......
精彩评论