The famous DX7 synthesizer requires that all voice files are prefixed by a 6 integer, leading 0s, sequence number, for the files to be recognized. Scrounging around on the internet, one can find many DX7 voice-file collections. I now have 3500-odd such .syx files and since I don't want to be swapping DX7 cartridges around all the time, it is much more convenient to put all the files into one DX7 cartridge/directory, with all the voice files named according to the 6-digit uniquely-numbered prefix requirement. Here is how to apply a sequential, unique prefix to a bunch of files in a directory.
Let's first gather all the downloaded files from their directories into one directory using the find command. The ~/sysex/voice directory is where DX7 emulators like Dexed and MiniDexed would expect to find their voice files, so we will use that.
~/sysex/voice $ find ~/Downloads -name "*.syx" -type f -exec cp {} . \; ~/sysex/voice $ ls | wc -l 3511
So, we have 3511 .syx files, and they are named like these examples:
~/sysex/voice $ ls
YAMAHA01.syx
YAMAHA02.syx
YAMAHA03.syx
etc...
The objective is to rename them all so that they end up being named something like this:
~/sysex/voice $ ls
000001_YAMAHA01.syx
000002_YAMAHA02.syx
000003_YAMAHA03.syx
etc...
The magic sauce to the solution is to use the nl-utility ("number lines"), which counts and prints line numbers in a stream, starting at 1, like this;
~/sysex/voice $ ls | nl 1 YAMAHA01.syx
2 YAMAHA02.syx
3 YAMAHA03.syx
etc...
To get the files to resemble the desired end result, we need to rename each file using the mv command. The series of commands would look something like this:
~/sysex/voice $ mv YAMAHA01.syx 000001_YAMAHA01.syx ~/sysex/voice $ mv YAMAHA02.syx 000002_YAMAHA02.syx ~/sysex/voice $ mv YAMAHA03.syx 000002_YAMAHA03.syx etc...
The mv command can be constructed by piping each output line of nl into awk. awk takes the first and the second strings, respectively identified by $1 (="1") and $2 (="YAMAHA01.syx"), and concatenates the mv command using its printf function, which is very similar to C's printf function:
~/sysex/voice $ ls | nl | awk '{printf("mv %s %06d_%s\n",$2, $1, $2)}
This gives me 3511 separate mv-commands. You would not want to do this by hand...
However, bear in mind that there may be some odd file names with spaces and other characters that may confuse both awk and the mv command, so it is essential to remove all spaces from the file names and to also enclose the file names with inverted commas to avoid problems when the shell executes the command. We use the version of rename by Larry Wall that comes with Mint Linux and can rename files to any desired regular expression pattern, in order to strip all the space characters from file names. Even in the case when there are multiple spaces in a file name - this is what the 'g' is for:
~/sysex/voice $ rename 's/ //g' *
The second issue is to enclose all file names in inverted commas, but since awk cannot directly print inverted commas, the inverted commas need to be ASCII-encoded in the awk script using the hex-code "\x27", which results in this slightly cryptic-looking script:
~/sysex/voice $ ls | nl | awk '{printf("mv \x27%s\x27 \x27%06d_%s\x27\n",$2, $1, $2)}'
Running this command gives us all the mv commands, complete with enclosed inverted commas around each file name:
~/sysex/voice $ mv 'YAMAHA01.syx' '000001_YAMAHA01.syx'
~/sysex/voice $ mv 'YAMAHA02.syx' '000002_YAMAHA02.syx'
~/sysex/voice $ mv 'YAMAHA03.syx' '000003_YAMAHA03.syx'
etc...
All that is required now is to execute them as they pass through the xargs pipeline executer.
~/sysex/voice $ ls | nl | awk '{printf("mv \x27%s\x27 \x27%06d_%s\x27\n",$2, $1, $2)}' | xargs
All the files are now named 000001_... to 003511_... and are ready to be copied to a DX7 cartridge, or into your Dexed directory.