You are not logged in.

#1 2011-09-17 03:45:17

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

[Solved] Selecting folder span in bash script

Hey all,

Recently, I decided to get an audio-book from Audible and discovered the mp3 player they advertise about is only for ipods.  This meant that the only legit way to transfer it to my mp3 player (an .aa file/DRM protected) was to use iTunes burn it to multiple cds.  Doingthis had the book span 14 disks and now I'm trying to put it back together.  I used a great program called 'ripit' to rip the files back to Linux and now I'm faced with the task of concatenating the files back together again.  Ripit ripped the disks to 14 separate folders:

Unknown Artist - Unknown Album
Unknown Artist - Unknown Album 1
Unknown Artist - Unknown Album 2
...
Unknown Artist - Unknown Album 13

To get these to appear in correct order I first rename the first album:

mv Unknown\ Artist\ -\ Unknown\ Album/ Unknown\ Artist\ -\ Unknown\ Album\ 0

replaced white spaces with hyphens (necessary for the next step):

find -name "* *" -type d | rename 's/ /-/g'

Zeropad the numbers to show in the right order (using this persons excellent script - http://www.walkingrandomly.com/?p=2850):

for i in *; do mv "$i" $(zeropad "$i"); done
#!/bin/bash
# zeropad
# Filter that will take input with basic numbering and zero pad it (i.e. file002)
# e.g. mv file1.png `$(zeropad) $i`
# http://www.walkingrandomly.com/?p=2850

num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}

So now my directories look like this:

Unknown-Artist---Unknown-Album-000
Unknown-Artist---Unknown-Album-001
...
Unknown-Artist---Unknown-Album-013

Now I'm trying to create a bash script that will put this mp3s back together again.  mp3cat is the right utility to do this so I need to create a bash script that I can tell what folders to use to put them together.  Originally the book from Audible came in three parts:

SK...part1.aa
SK...part2.aa
SK...part3.aa

part 1 covers directories 000 to 004, part 2 005 to 008, part 3 009 to 013.  The script though I'd like to be generic (to be able to accept input if I decided to ever do this again).  Here it is thus as I have it so far figured out:

echo "Join multiple mp3s from which folders?"
echo -n "First folder number [0xx]: "
read first_folder
echo -n "   to folder number [0xx]: "
read final_folder
echo -n "  Name of file [name].mp3: "
read filename
for f in Unknown-Artist---Unknown-Album-[$first_folder-$final_folder]; do
  cat "$f"/*.mp3 | mp3cat - - > "$filename".mp3
done

I'd like to be able to input which directory to begin with and then input which directory to end with.  My use of [$first_folder-$final_folder] here shows my limited use of bash and I know that this this is only going to work for a single digit.  Any ideas what I can do here?

Last edited by Gen2ly (2011-09-19 02:25:04)


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#2 2011-09-17 06:55:33

rockin turtle
Member
From: Montana, USA
Registered: 2009-10-22
Posts: 227

Re: [Solved] Selecting folder span in bash script

Try this:

#!/bin/bash

declare -a filelist

for (( i="$1"; i <= "$2"; i++ )); do
	suffix=$(printf '%03d' "$i")
	f="Unknown-Artist---Unknown-Album-$suffix"
	filelist+=($(ls $f/*))
done

cat "${filelist[@]}" | mp3cat - - > "$3.mp3"

This assumes that the files within the directory will be listed in the correct order.  Then run it:

$ scriptname 0 4 filename

Last edited by rockin turtle (2011-09-17 07:24:14)

Offline

#3 2011-09-17 14:09:21

moetunes
Member
From: A comfortable couch
Registered: 2010-10-09
Posts: 1,033

Re: [Solved] Selecting folder span in bash script

I think bashs' brace expansion might help here. Try something like:

# Join multiple audio book cds to singular mp3.  Audible download aa ripped to audio cd, then used 'ripit' to mp3.  This script joins multiple folders mp3s into their original large mp3.

echo "Join multiple mp3s from which folders?"
echo -n "First folder number [0xx]: "
read first_folder
echo -n "   to folder number [0xx]: "
read final_folder
echo -n "  Name of file [name].mp3: "
read filename
for f in Unknown-Artist---Unknown-Album-{$first_folder..$final_folder}; do
  cat "$f"/*.mp3 | mp3cat - - > "$filename".mp3
done

Check man bash for how brace expansion works if in doubt.

Cheers


You're just jealous because the voices only talk to me.

Offline

#4 2011-09-17 14:31:51

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: [Solved] Selecting folder span in bash script

@Gen2ly Looks like a lot of unnecessary work and detail here. Could have defined the problem simpler and clearer...
@rockin turtle The `ls` call should be avoided, moreover, any whitespace in filenames breaks it.
@moetunes That won't work. Only literals like {0..4} are expanded, since brace expansion is performed before any other expansions.

Last edited by lolilolicon (2011-09-17 14:32:15)


This silver ladybug at line 28...

Offline

#5 2011-09-17 18:44:45

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: [Solved] Selecting folder span in bash script

lolilolicon wrote:

@Gen2ly Looks like a lot of unnecessary work and detail here. Could have defined the problem simpler and clearer...

Agreed.  Cleaned up post a little bit but left details in as I think they might be useful to other people down the road (I hope smile).

rockin turtle wrote:

Try this:

#!/bin/bash

declare -a filelist

for (( i="$1"; i <= "$2"; i++ )); do
	suffix=$(printf '%03d' "$i")
	f="Unknown-Artist---Unknown-Album-$suffix"
	filelist+=($(ls $f/*))
done

cat "${filelist[@]}" | mp3cat - - > "$3.mp3"

This assumes that the files within the directory will be listed in the correct order.  Then run it:

$ scriptname 0 4 filename

Was afraid my basic script would become more complicated.  From what I know of the i and i++ stuff this is a counting thing.  Pretty neat.  Unfortunately I'm getting the problem that lolilolicon referred.  The mp3s have spaces so it's not working with 'ls'.  Is there another tools we can use?


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#6 2011-09-17 19:04:20

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solved] Selecting folder span in bash script

Shell globbing is what lolilolicon should have pointed you towards...

filelist+=("$f"/*)

Offline

#7 2011-09-18 03:12:58

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: [Solved] Selecting folder span in bash script

Yup, could have been more explicit. Pathname Expansion is the relevant section in bash(1) man page.


This silver ladybug at line 28...

Offline

#8 2011-09-18 12:51:30

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: [Solved] Selecting folder span in bash script

If there are spaces in the filenames then using globbing won't change anything. When stored in an array the new elements are split at spaces. This has the same problem as using ls. edit: ok so, "newer" versions of bash won't split the elements at spaces but the spaces still screw up when the array is expanded to command arguments.

As usual all problems of existence are just a primitive form of bending. I mean, sorting! Crap. No need to remove the spaces and rename everything. sort and awk like spaces.

# Must... have... number!

mv "Unknown Artist - Unknown Album" "Unknown Artist - Unknown Album 0" \
    2>/dev/null

# Sort & awk read as many number chars as possible, then give up.
# ./Unknown Artist - Unknown Album 1/Track 1.mp3
# (Fields)                      6_/*^^^^^^ *^^^^\_7

find . -name '*.mp3' | sort -n -k6 -k7 | \
    # $6+0 coerces $6 into a number.
    awk -v beg="$1" -v end="$2" '$6+0 >= beg && $6+0 <= end' |
    # Use NULL chars instead of newlines to make xargs happy.
    tr '\n' '\0' | xargs -0 cat
    # Without NULL chars and -0, xargs splits on lines AND spaces. Bad.

Instead of changing the data (paths) to make it sort lexicographically, I simply sorted the data explicitly. Two args: beginning number and ending number. It's probably too late, since you renamed everything but maybe you can use the tr | xargs trick. Avoid using bash arrays or get rid of the spaces in the filenames.

Last edited by juster (2011-09-18 13:02:59)

Offline

#9 2011-09-18 13:08:15

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solved] Selecting folder span in bash script

Globbing plays quite well with spaces. If you're having problems seeing this in an array, then I assume you're not quoting properly on expansion.

$ touch one "two three" four "five six"
$ f=(*)
$ printf '%s\n' ${f[@]}
five
six
four
one
two
three
$ printf '%s\n' "${f[@]}"
five six
four
one
two three
$ printf '%s\n' "${f[*]}" #for the sake of completeness
five six four one two three

Offline

#10 2011-09-18 13:25:26

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: [Solved] Selecting folder span in bash script

Ah you are right, I forgot the double quotes.

Offline

#11 2011-09-19 02:24:35

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: [Solved] Selecting folder span in bash script

Thanks for the help guys.  rockin turtle, your script was very helpful.  Also, thank you falconindy for the clarification.  The only think I changed was:

f="Unknown Artist - Unknown Album $suffix"

because I learned that this code will work with spaces.  Again, appreciate the help.


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

Board footer

Powered by FluxBB