command line bulk rename

2019-07-16 04:37发布

问题:

I have files in multiple subfolders, I want to move them all to one folder. Then I like to rename those files.

/foo/A1000-foobar1412.jpg
/foo/A1000-foobar213.jpg
/foo/A1000-foobar314.jpg
/foo1/B1001-foobar113.jpg
/foo2/C1002-foobar1123.jpg
/foo2/C1002-foobar24234.jpg

What I would like to get is:

../bar/A1000-1.jpg
../bar/A1000-2.jpg
../bar/A1000-3.jpg
../bar/B1001-1.jpg
../bar/C1002-1.jpg
../bar/C1002-2.jpg

So what I do so far is:

find . -name "*.jpg" -exec mv {} ../bar/ \;

But now I'm stuck at renaming the files.

回答1:

Here is a script that just takes the desired basename of the file and appends an incremental index depending on how many files with the same basename already exist in the target dir:

for file in $(find . -name "*.jpg")
do
  bn=$(basename $file)
  target_name=$(echo $bn | cut -f 1 -d "-")
  index=$(($(find ../bar -name "$target_name-*" | wc -l) + 1))
  target="${target_name}-${index}.jpg"

  echo "Copy $file to ../bar/$target"
  # mv $file ../bar/$target
  cp $file ../bar/$target
done

With this solution you can't just put an echo in front of the mv to test it out as the code relies on real files in the target dir to compute the index. Instead use cp instead (or rsync) and remove the source files manually as soon as you are happy with the result.



回答2:

Try this (Not tested):

for file in `find . -name "*.jpg" `
do
  x=$(echo $file | sed 's|.*/||;s/-[^0-9]*/-/;s/-\(.\).*\./-\1./')
  mv $file ../bar/$x
done