Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Background

Rename one set of files based on a name that corresponds to another set, using a sort order based on file size to match the file names. The files from both sets have approximately the same sizes. Close enough that when sorted by file size both lists are in the same order. The number of files in each set is exactly the same.

Problem

First file set:

master~$ for f in $(ls -S); do echo $f; done
06-AudioTrack_06.flac
08-AudioTrack_08.flac
01-AudioTrack_01.flac
05-AudioTrack_05.flac
02-AudioTrack_02.flac

Second file set:

corrupt~$ for f in $(ls -S); do echo $f; done
Groove_de_V..flac
Jump.flac
Do_You_Savvy.flac
Gershwins_Blues.flac
Blue_Skies.flac
If_I_Had_A_Ribbon_Bow.flac

Question

How do you rename the first set as follows:

06-Groove_de_V..flac
08-Jump.flac
01-Do_You_Savvy.flac
05-Gershwins_Blues.flac
02-Blue_Skies.flac

Script

So far...

master~$ for f in $(ls -S); do
  IDX=$(echo $f | awk '{print substr( $1, 1, 2 )}');
  echo "mv $i $IDX-";
done

Produces:

mv 06-AudioTrack_06.flac 06-
mv 08-AudioTrack_08.flac 08-
mv 01-AudioTrack_01.flac 01-
mv 05-AudioTrack_05.flac 05-
mv 02-AudioTrack_02.flac 02-

Thank you!

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

Some modifications to your script eliminating the need for AWK and simplifying the incrementing of the index variable. It will also now correctly handle filenames that include spaces.

#!/bin/bash

index=0

# Store the names of original (corrupt) files
while read -r f
do
    corrupt[index++]=${f##*/}
done < <(ls -S "$1"/*.flac)

index=0

while read -r f
do
    idx=${f:0:2}
    original=${corrupt[index++]}
    echo mv "$f" "$idx-$original"
done < <(ls -S *.flac)
share|improve this answer
    
@Dennis: Thank you for teaching me new bash techniques. I wasn't concerned about spaces in file names because they were converted to underscores upon encoding. Still, this is a much more robust solution. –  Dave Jarvis Mar 10 '11 at 20:03
    
@Dennis: Found a slight bug (in both our versions): file names with parentheses. Practically, though, it matters little as I can fix those by hand. –  Dave Jarvis Mar 10 '11 at 20:31
    
@DaveJarvis: Can you show me an example and tell me in what way it fails? None of the examples in your question have parentheses and there's nothing in my code that should choke on them. –  Dennis Williamson Mar 10 '11 at 21:57
    
@Dennis: It's a bug when the mv statements execute. The parentheses aren't escaped (and neither are ampersands). There was no way you could have known, though, because I did not show you the entire list of possible file names. –  Dave Jarvis Mar 10 '11 at 22:07
    
@DaveJarvis: mv shouldn't have any problems with filenames that include those characters unless there's a name collision. –  Dennis Williamson Mar 10 '11 at 22:11
show 5 more comments
#!/bin/bash

let INDEX=0

# Store the names of original (corrupt) files
for f in $(ls -S "$1"/*.flac); do
  corrupt[$INDEX]=$(basename "$f");
  let INDEX="$INDEX+1"
done

let INDEX=0

for f in $(ls -S *.flac); do
  IDX=$(echo $f | awk '{ print substr( $1, 1, 2 ) }');
  original=${corrupt[$INDEX]};

  echo "mv $f $IDX-$original";

  let INDEX="$INDEX+1"
done
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.