1

I have 3 directories on my Ubuntu machine, named abc, xyz and pst. In each directory, I have approximately 7 files with different names. I want to rename each file like abc_1.txt, abc_2.txt, abc_3.txt, abc_4.txt, abc_5.txt, abc_6.txt, abc_7.txt. Similarly, with the xyz and pst directories.

To clarify, I tried one of the answers below:

i=0
for f in */* ; do i=$(( i+1 )) fp=$(dirname "$f"); ext="${f##*.}" ; echo "$f" "$fp"/"$fp"_"$i"."$ext" ;done

And the output is:

123/1.jpg 123/123_1.jpg
123/2.jpg 123/123_2.jpg
123/3.jpg 123/123_3.jpg
2275/2275_1.jpg 2275/2275_4.jpg
2275/2275_2.jpg 2275/2275_5.jpg
2275/2275_3.jpg 2275/2275_6.jpg
2275/2275_4.jpg 2275/2275_7.jpg
2275/2275_5.jpg 2275/2275_8.jpg
2275/2275_6.jpg 2275/2275_9.jpg
2275/2275_7.jpg 2275/2275_10.jpg
2275/2275_Thumbs.db 2275/2275_11.db
456/1.jpg 456/456_12.jpg
456/2.jpg 456/456_13.jpg
456/3.jpg 456/456_14.jpg

But I want the result to be like this:

123/1.jpg 123/123_1.jpg
123/2.jpg 123/123_2.jpg
123/3.jpg 123/123_3.jpg
2275/2275_1.jpg 2275/2275_1.jpg
2275/2275_2.jpg 2275/2275_2.jpg
2275/2275_3.jpg 2275/2275_3.jpg
2275/2275_4.jpg 2275/2275_4.jpg
2275/2275_5.jpg 2275/2275_5.jpg
2275/2275_6.jpg 2275/2275_6.jpg
2275/2275_7.jpg 2275/2275_7.jpg
2275/2275_Thumbs.db 2275/2275_8.db
456/1.jpg 456/456_1.jpg
456/2.jpg 456/456_2.jpg
456/3.jpg 456/456_3.jpg

How can I do this?

terdon
  • 234,489
  • 66
  • 447
  • 667
Shubham
  • 11
  • 1
  • Hello Shubham. What have you tried so far? – roaima Apr 15 '19 at 14:09
  • Related: [Rename files with consecutive numbers](https://unix.stackexchange.com/a/497960/100397) and [Batch rename files to a sequential numbering](https://unix.stackexchange.com/questions/420927/batch-rename-files-to-a-sequential-numbering). – roaima Apr 15 '19 at 14:11
  • 1
    Shubham. Please [edit your question](https://unix.stackexchange.com/posts/512580/edit) to add information, using the formatting bar as necessary (for example select code and click the `{}` button to format it). Don't put updates in an Answer, and don't put complex replies in comments. Try to make it easy for us to help you. – roaima Apr 15 '19 at 15:06
  • @roaima again, this is not a dupe -- the OPs wants the dirname included in the generated filename. while it *may* be possible to adapt the answers from there to [this case](https://unix.stackexchange.com/a/512594/308316) (not really sure about it), it's not trivial. –  Apr 15 '19 at 16:07
  • @roaima I have to agree with Mosvy. While the proposed dupe is certainly relevant and hepful, you need to know your way around the shell to adapt either answer to get the directory's name included. Also, close voters, please try not to close as dupes of questions already closed as dupes. use the final dupe target instead. – terdon Apr 15 '19 at 23:09
  • @roaima done! I took the liberty of also adding a link to the duplicate's duplicate. I hope you don't mind. – terdon Apr 16 '19 at 00:29

2 Answers2

0
cd /path/to/abc; cnt=0; for i in *.*; do mv "$i" "${PWD##*/}_$((++cnt)).${i##*.}"; done
  • for each directory abc, xyz, ... you have to cd into that directory
  • *.* used to only select the files with suffix
  • replace mv with echo to see what the result would look like before you mess around

Edit:

If you want this for multiple directories and reset the counter in each directory.

Oneliner:

for i in */*.*; do [ "$dn" != "${i%/*}" ] && cnt=0; dn="${i%/*}"; mv "$i" "${dn}/${dn}_$((++cnt)).${i##*.}"; done

Pretty printed:

for i in */*.*; do
    # reset counter if different directory or dn is unset
    [ "$dn" != "${i%/*}" ] && cnt=0

    # set directory name
    dn="${i%/*}"

    # move file
    mv "$i" "${dn}/${dn}_$((++cnt)).${i##*.}"
done
Freddy
  • 25,172
  • 1
  • 21
  • 60
0

For better understanding please review this:- I want to do this in script so i got one command i.e.

i=0
for f in */* ; do i=$(( i+1 )) fp=$(dirname "$f"); ext="${f##*.}" ; echo "$f" "$fp"/"$fp"_"$i"."$ext" ;done

And the output is like-

123/1.jpg 123/123_1.jpg
123/2.jpg 123/123_2.jpg
123/3.jpg 123/123_3.jpg
2275/2275_1.jpg 2275/2275_4.jpg
2275/2275_2.jpg 2275/2275_5.jpg
2275/2275_3.jpg 2275/2275_6.jpg
2275/2275_4.jpg 2275/2275_7.jpg
2275/2275_5.jpg 2275/2275_8.jpg
2275/2275_6.jpg 2275/2275_9.jpg
2275/2275_7.jpg 2275/2275_10.jpg
2275/2275_Thumbs.db 2275/2275_11.db
456/1.jpg 456/456_12.jpg
456/2.jpg 456/456_13.jpg
456/3.jpg 456/456_14.jpg

But i want this ouptut is like -

123/1.jpg 123/123_1.jpg
123/2.jpg 123/123_2.jpg
123/3.jpg 123/123_3.jpg
2275/2275_1.jpg 2275/2275_1.jpg
2275/2275_2.jpg 2275/2275_2.jpg
2275/2275_3.jpg 2275/2275_3.jpg
2275/2275_4.jpg 2275/2275_4.jpg
2275/2275_5.jpg 2275/2275_5.jpg
2275/2275_6.jpg 2275/2275_6.jpg
2275/2275_7.jpg 2275/2275_7.jpg
2275/2275_Thumbs.db 2275/2275_8.db
456/1.jpg 456/456_1.jpg
456/2.jpg 456/456_2.jpg
456/3.jpg 456/456_3.jpg
Shubham
  • 11
  • 1
  • try `for d in *; do i=0; for f in "$d/"*; do test -f "$f" || continue; dn=${f%"/${f##*/}"}; echo "$f" "$dn/${dn}_$((i=i+1))${f#"${f%.*}"}"; done; done` –  Apr 15 '19 at 15:58