2

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.

steros
  • 1,794
  • 2
  • 26
  • 60
  • How many duplicates? http://stackoverflow.com/questions/12292232/rename-batch-of-file-in-unix; http://stackoverflow.com/questions/10977543/rename-multiple-files-linux-ubuntu; http://stackoverflow.com/questions/417916/how-to-do-a-mass-rename; http://stackoverflow.com/questions/3540490/batch-renaming-using-shell-script; ... – Jonathan Leffler Nov 27 '12 at 19:40
  • not one is like my scenario... – steros Nov 28 '12 at 20:21
  • OK...because? Because of the numbering within a prefix? What's supposed to happen when C1002 has 10 `.jpg` files? `C1002-10.jpg`? `C1002-01.jpg`, `C1002-02.jpg`, ... too? What determines which of `/foo2/C1002-foobar1123.jpg` and `/foo2/C1002-foobar24234.jpg` becomes `C1002-1.jpg` anyway? Does it matter? – Jonathan Leffler Nov 28 '12 at 20:23

2 Answers2

2

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.

stolzem
  • 354
  • 1
  • 7
1

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
Guru
  • 16,456
  • 2
  • 33
  • 46
  • change to `echo mv $file ../bar/$x`, use that output to confirm all is working as needed, then remove echo OR end the loop with `done | bash`. Good luck to all. – shellter Nov 27 '12 at 15:01