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 awhile read
loop is a neat way of reading the output offind
one line at a time. It's nice because it'll process the files asfind
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 tofind
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 asecho "$OLD" | sed
, just a little fancier...[ "$OLD" != "$NEW" ] && mv
is 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
精彩评论