Rename files based on simple text file

Hello!

New here although not completely new to Unix.
I wonder how I could rename files based on the data found in a simple textfile.
It goes like this:

I have 4 files

1 ldfgkkfjslkdfjsldkfjsf.wav
2 nndsdflksdjf.wav
3 sdflksjdf jjsdflsdfl.wav
4 dkadsdddd.wav

Textfile.txt looks like this:

1 ^t Some ^t Data
2 ^t Other ^t Info & Stuff
3 ^t Yet ^t More Data
4 ^t To the ^t End

^t being tab, or some other apropriate separation character

I want files to look like this:

01 - Some -Data
02 - Other - Info & Stuff
03 - Yet - More Data
04 - To the - End

I realize there's a problem if the text document does not match the number of files but that does not need to be error handled. It does not need to be fool proof, I will do this one folder at a time, checking for errors manually. Each folder contains some 10-30 files. I want leading zeroes up to 9 if possible but it's not extremely important.

Background: These are mediafiles converted from tape archives. The titles are in a separate textfile for each converted tape. Each tapes goes into a separate folder.

Not sure I fully understand.
You want to rename several ".wav" files in a directory - not more than 30, so definitely NOT 3 digits - to new names without the ".wav" extension based on the contents of a text file indexed by the leading number in the ".wav" file name?

Any attempts / ideas / thoughts from your side? Any preferred tools?

Sorry for late answer, been busy.

Yes, I think you got it just right.
The file with index 1 get's it name from line 1 in the document.
The file with index 23 get's it name from line 23 in the document.
Each line begins with a digit already and these should in almost all cases coincide with the line number. No file exceeds 99 lines.

I read the manual for grep and also had a look at commands like sed and I know I can pipe the output of one command to the input of another command but I can't figure out how to do that in this case. In pseudocode it would be something like:

Start
n = 1
While not EOF in document.txt
A = contens of line n in document.txt
rename file n*.wav to A
end while

If it's possible I would rather do this with a simple commad in Unix rather than build a script. It's not meant to be advanced in any way, handling exceptions and things like that. If it works 8 times out of 10 I'm fine.

---------- Post updated at 08:57 PM ---------- Previous update was at 08:47 PM ----------

In this post there's a similar question but I don't have the corresponding filename in the document so i can't use that although it's quite similar.

Why are the filename and message content in different files? One little mistake will create a giant mess.

In any case, this being UNIX, there's ways to hedge your bets... I'd make an 'out' folder and create links in it, instead of renaming the original files. If something goes wrong, you're not left with all your files irreparably misnamed, just a bit of trash you can delete and start over.

#!/bin/bash
mkdir -p ./out/

exec 5<filenames
exec 6<filetitles
while read LINE FILENAME <&5 && IFS=$'\t' read NUM FILETITLE <&6
do
        if [ "$NUM" -ne "$LINE"]
        then
                echo "Numbers do not match?"
                continue
        fi

        FILETITLE="${FILETITLE//$'\t'/ - }" # Change tab into ' - '        
        ln "$FILENAME" out/"${NUM} ${FILETITLE}"
done

exec 5<&- # Close files
exec 6<&-

This should create links in the ./out/ folder of the right names.

Try also

while IFS=" " read Nr NFN
  do    NZ="0$Nr"
        echo mv "$Nr "*".wav" "${NZ#${NZ%??}} ${NFN// /-}"
  done < file

Remove the echo command if happy with the proposals.

Thanks, the files originate from an old audio tape archive which at one point has been digitized. The textfiles where created a long time ago on a separate system.

I will have a look at your script � thank you.

---------- Post updated at 09:28 PM ---------- Previous update was at 09:10 PM ----------

That seems to work about right.
I have two problems though.
The filenames looks like this:
03 ELO---Happy-Haunting

But I would prefer:
03 - ELO - Happy Haunting

I need some sort of separation between the thre fields which are track number, artist, title.
If blanks needs to be converted then perhaps underscore is better? Like: " 02_-_artist_-_title_song.wav"
I could easily convert underscore back to space afterwards.

Is this the section where blanks are converted?

Also, it seems like some folders have their files numbered like this:
01 fsfsdf.wav
02 dfgh ert.wav
...
11 abc def.wav

Leading zeroes below ten. Where do I modify the script for this?

Does this mean you do or don't want leading zeroes?

Leading zeroes is the preffered chioce for 1-9. Sorry for confusing things.

I also do realize now that'-' is probably a very bad separation character since it can be part of song titles. That's why I used ^t (tab) initially. I think this will be the best chioce, I can easily convert the separation character prior to generating the text files.

Does this mean you want tabs in the filenames? That is possible but will make them somewhat difficult to type.

If there are three dashes, there have been three spaces. Check / edit the input file.

Sorry? Let us look back into post#1:

Thank's for helping out.

You're right. That's probably not a good idea. I guess some other common separation character that's not usually part of things like songtitles would be better. The data from the filenames whill later be extracted and converted to metadata in the file. I believe I can use most characters like for instance '#' or '=' for separation purposes.

I tried your script but I can not make it work. I get:

./script.sh: line 8: [: missing `]'

Also I'm not shure what filenames should be replaced with. Filetitles I guess is the file with the requested names. But there is no file with the current filenames. I tried to create on using mv *.wav > filenames.txt and then run the script but that didn't work

I suggest @ or %, which have no special meaning by themselves in most shells.

Yes, that's my prefered output. But the input may be both with and without leading zeroes but maybe that's not a problem? It works in both cases?

Regarding separation character, Corona688 helped me realize '-' was a bad choice so unfortunately it got a bit confused.

Generally your small script works but for me to tweak it I need to understand what this part of the code does:

${NZ#${NZ%??}} ${NFN// /-}

Also, this part, which I guess has to do with leading zeroes is a bit unclear to me:

NZ="0$Nr"

Yes, NZ="0$Nr" adds a leading zero. 1 --> 01 ; 12 --> 012

${NZ#${NZ%??}} uses shell's "parameter expansion: remove prefix / suffix pattern" to chop off leading characters preserving the last two.

${NFN// /-} uses "parameter expansion: pattern substitution" to replace all spaces in a string with dashes. You could try to apply it repeatedly to reduce / remove the multiple space occurrences.
See e.g. man bash for reference of the two builtins.

OK, thanks. I can probably make this work.
Although man-pages is the place where I always get lost you gave me the secret word: "parameter expansion" so now I can Google it instead finding examples!