0

I have a couple of folders that are audiobooks. The files are numbered and I want to convert them to one file. I used the following script to convert them:

    #!/bin/bash 
    if [ ! -d mp3 ]; then
    mkdir -p mp3;
    fi;
    for f in ./*.flac; do echo "file '$f'" >> mylist.txt; done
    ffmpeg -f concat -safe 0 -i mylist.txt -b:a 320k mp3/title.mp3
    [ -e mylist.txt ] && rm mylist.txt

My problem is that I have to rename the first ten files because they are not in the right order. The files are named 1 - Title, 2 - Title, 3 - Title and so on. To get the right order I have to rename them to 01 - Title, 02 - Title, ..., 09 - Title. How can I do that with a bash script ? Furthermore it would be nice, if the playlist.m3u file would be changed accordingly.

Thanks for your help.

@Cyrus posted the right Link to solve my problem. The solved script ist:

#!/bin/bash
if [ ! -d mp3 ]; then
mkdir -p mp3;
fi;
for f in ./*.flac; do echo "file '$f'" >> mylist2.txt; done
sort -V mylist2.txt >> mylist.txt
rm mylist2.txt
ffmpeg -f concat -safe 0 -i mylist.txt -b:a 320k mp3/title.mp3
[ -e mylist.txt ] && rm mylist.txt
codeforester
  • 39,467
  • 16
  • 112
  • 140
Flavorum1
  • 3
  • 2
  • This might help: [Sorting strings with numbers in Bash](https://stackoverflow.com/q/17061948/3776858) – Cyrus Sep 09 '18 at 18:30
  • 1
    Thank you, I changed the script 'for f in ./*.flac; do echo "file '$f'" >> mylist2.txt; done sort -V mylist2.txt >> mylist.txt rm mylist2.txt' – Flavorum1 Sep 09 '18 at 18:49

1 Answers1

0

You can use sort -n for this. I did this:

~/SO $ l
total 8
-rw-rw-r-- 1 user user    0 Sep  9 14:49 12 - Title
-rw-rw-r-- 1 user user    0 Sep  9 14:49 1 - Title
-rw-rw-r-- 1 user user    0 Sep  9 14:49 22 - Title
-rw-rw-r-- 1 user user    0 Sep  9 14:49 2 - Title

~/SO $ ls | sort -n
1 - Title
2 - Title
12 - Title
22 - Title

just to show you I did not "cheat", here are the aliases:

alias l='ls -lp'
alias ls='ls --color=auto'

Hence you can use:

ls | sort -n | while read file
do
    echo $file
done

the echo here is just to show that the order of files processed does respect the numerical values.

Nic3500
  • 8,144
  • 10
  • 29
  • 40
  • Thank you for your help. I used sort -n to solve my problem. – Flavorum1 Sep 09 '18 at 19:14
  • It is important to note that this variant only works with file names that do not contain spaces or line breaks. – Cyrus Sep 09 '18 at 19:18
  • Nope, I did it with file names that contain spaces. – Nic3500 Sep 09 '18 at 19:18
  • @Flavorum1: if it solves your problem, you can accept the answer with the ckeck mark on the left of the answer :-) – Nic3500 Sep 09 '18 at 19:18
  • @Nic3500: Please test your while read loop with your files. – Cyrus Sep 09 '18 at 19:20
  • I did twice. Before I posted, after you posted the comment. I did this: `touch "1 - title";touch "2 - title";touch "12 - title"; ls | sort -n | while read file; do echo "BEFORE${file}AFTER"; done` and I get the files sorted like the OP wanted. Bash v4.3.48 on Mint 18. The "BEFORE" and "AFTER" are just to make sure I did not add anything, or skip lines. – Nic3500 Sep 09 '18 at 19:24
  • @cyrus: you can post the link to your solution as an answer. **Flavorum1**: you can accept cyrus' version instead of mine, once it is posted. – Nic3500 Sep 09 '18 at 19:27
  • @Nic3500: It's all right, sorry, I made a big mistake testing. – Cyrus Sep 09 '18 at 19:32
  • @cyrus posted a comment, therefore I cannot mark it as a solution. Both solutions seems to be working. – Flavorum1 Sep 09 '18 at 19:40
  • The working solution of @Nic3500 is: 'ls | sort -n | while read file do if [[ $file == *.flac ]]; then echo "file '$file'" >> mylist2.txt; fi; done' – Flavorum1 Sep 09 '18 at 19:52