Sandra Schlichting
Sandra Schlichting

Reputation: 26056

Renaming files with double loop?

I have the below 28 files, where I would like to rename them to

1-1
1-2
...
7-1
7-4

plus the correct file extension. What I have tried it

for f in *; do
  for i in $(seq 7); do
    for j in $(seq 4); do
      mv $f $i-$j.${f#*.}
     done
   done
done

but this keeps renaming only the first file.

The order in which they are renamed doesn't really matter.

Question

Can anyone figure out how to rename the files, so they get the $j-$i naming?

0764342e9a7b64d67b13478443cc6657.png  43fd06b017043443817df07073d76447.png  933441d5176a82b2fdd17fcecb061f76.png
1769998f64f45708ab5660453a76bcd9.png  460c50f9498171d8b3b13415692ba744.png  9638e66b9c7ad1a958a12dcb19918e82.png
1f32eab75790c4ec79dfeeb363381351.jpg  4ba8abdc7e43864ec79d432e9c259ff5.png  9d28f3c61dca4daaecc7f257b4ee09be.jpg
237b4de6ee17bb5033d7b17660ceef75.png  5b09795f9eef920da1207b2549cd5d80.png  c1d0c1520d62a811f9de297eecc08235.png
288ac636a508b903ef1d5c8c914a531c.png  60eff92e2dcf2192449c47fdb94551a1.jpg  e2080072a8615f3016046f396ccba40f.png
2aeddcc1c52b32d81331c4be957bbfa4.png  6960cdb5cc9951e96f4a95aba44f9377.jpg  e2d25004b63c60f83b690d3394277d4d.jpg
2b9f5508623ef64f8f0e81ae6bb1fb24.png  6ab9951011bad2bed060658ac58ea7c1.png  e6989ec43b8fcab262b6a414313b6538.png
36f4a71039adaffdd3e173ab302e5142.png  6b0f52f96bce76c004be0a3d70e2ef3f.png  e8e7f53b39b632427333d700f34b2c5b.png
392da2e9809cca9d9357b3d1f4868de1.jpg  6c8a9665ee8a3e251bad53748815cedd.png
3e7bfa5919f5d49d3dfc27574f346337.png  8fd5ec47f3d31844be60c1350361905e.jpg

Upvotes: 1

Views: 50

Answers (2)

Benjamin W.
Benjamin W.

Reputation: 52536

Creating two pseudo files, pasting them together and using sed to turn each line into a command:

paste <(printf '%s\n' *) <(printf '%s\n' {1..7}-{1..4}) \
    | sed 's/^/mv /;s/\(\....\)\(.*\)/\1\2\1/' \
    | bash

The output of the paste command is something like

$ paste <(printf '%s\n' *) <(printf '%s\n' {1..7}-{1..4})
0764342e9a7b64d67b13478443cc6657.png    1-1
1769998f64f45708ab5660453a76bcd9.png    1-2
1f32eab75790c4ec79dfeeb363381351.jpg    1-3
237b4de6ee17bb5033d7b17660ceef75.png    1-4
288ac636a508b903ef1d5c8c914a531c.png    2-1
2aeddcc1c52b32d81331c4be957bbfa4.png    2-2
2b9f5508623ef64f8f0e81ae6bb1fb24.png    2-3
36f4a71039adaffdd3e173ab302e5142.png    2-4
392da2e9809cca9d9357b3d1f4868de1.jpg    3-1
3e7bfa5919f5d49d3dfc27574f346337.png    3-2
<snip>

and so on; sed turns this into

mv 0764342e9a7b64d67b13478443cc6657.png 1-1.png
mv 1769998f64f45708ab5660453a76bcd9.png 1-2.png
mv 1f32eab75790c4ec79dfeeb363381351.jpg 1-3.jpg
mv 237b4de6ee17bb5033d7b17660ceef75.png 1-4.png
mv 288ac636a508b903ef1d5c8c914a531c.png 2-1.png
mv 2aeddcc1c52b32d81331c4be957bbfa4.png 2-2.png
mv 2b9f5508623ef64f8f0e81ae6bb1fb24.png 2-3.png
mv 36f4a71039adaffdd3e173ab302e5142.png 2-4.png
mv 392da2e9809cca9d9357b3d1f4868de1.jpg 3-1.jpg
mv 3e7bfa5919f5d49d3dfc27574f346337.png 3-2.png
<snip>

and piping to bash runs it.

Upvotes: 2

Freddy
Freddy

Reputation: 4718

You could create an array containing the new prefixes and then loop over the filenames and fetch the corresponding array element.

# the convoluted way to create the array (don't use it, see below)
fnames=()
for i in {1..7}; do
  for j in {1..4}; do
     fnames+=("$i-$j")
  done
done

# the short way using two brace expansions, credits go to @Benjamin W.
fnames=({1..7}-{1..4})

idx=0
for f in *; do
  mv "$f" "${fnames[idx++]}.${f#*.}"
done

Upvotes: 5

Related Questions