HOEKSTRA.CO.UK

DEXED is a software emulator of the DX7 synth and can be played through a MIDI keyboard.
DEXED is a software emulator of the DX7 synth and can be played through a MIDI keyboard.

I have scrounged 3500-odd DX7 synthesizer voice files from various sources, and many have similar names. For the DX7 emulator to access them all, they need to be in only one directory,  ~/sysex/voice. and each filename must start with a unique 6-digit prefix. Here is how to apply such 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.