Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 12
My music library is arranged like: Code: /data/music/Artist_-_Album[alac]/*.m4a I need to be able to keep a copy of these in another format (apple lossless) and I'd want that like: Code: ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jan 2014
    Posts
    7

    bash: help creating folders using substitutions (music transcoding)


    My music library is arranged like:

    Code:
    /data/music/Artist_-_Album[alac]/*.m4a
    I need to be able to keep a copy of these in another format (apple lossless) and I'd want that like:

    Code:
    /data/music/Artist_-_Album[flac]/*.flac
    This one liner is good at traversing directories and converting items to flac, but it leaves all of the files in the source directory... not optimal.

    Code:
    for f in /data/music/**/*.m4a; do avconv -i "$f" "${f%.m4a}.flac"; done
    How can I change/edit/add to this script to make the output files to into a different folder that is named appropriately as shown above?

  2. #2
    Linux Engineer
    Join Date
    Dec 2013
    Posts
    1,294
    There's probably a lot better ways to do it but I think this would work - assuming alac doesn't appear in the path before the one you want to switch:
    Code:
    for f in /data/music/**/*.m4a; do avconv -i "$f" "$(echo ${f%.m4a}.flac | sed s/alac/flac/)"; done

  3. #3
    Just Joined!
    Join Date
    Jan 2014
    Posts
    7
    Sadly avconv won't create the output directory on it's own... unless there is an option for it somewhere that I don't know about

  4. #4
    Linux Engineer
    Join Date
    Dec 2013
    Posts
    1,294
    Quote Originally Posted by Underoo View Post
    Sadly avconv won't create the output directory on it's own... unless there is an option for it somewhere that I don't know about
    Now it's getting ugly
    Code:
    for f in /data/music/**/*.m4a; do mkdir $(dirname $(echo $f | sed s/alac/flac/)); avconv -i "$f" "$(echo ${f%.m4a}.flac | sed s/alac/flac/)"; done
    (untested)

  5. #5
    Linux Engineer docbop's Avatar
    Join Date
    Nov 2009
    Location
    Woodshed, CA
    Posts
    941
    if the tool doesn't have option to set output target then just add a mv command to your script.

  6. #6
    Linux Guru
    Join Date
    Jul 2004
    Posts
    4,593
    Although not exactly the same as what you are doing, I have a script that will automatically transcode my wave files into mp3 files, tag them and as a bonus create a playlist for the files.

    You will need these programs installed:

    ffmpeg
    id3ren
    fapg

    I am using the folder names and "-" to tag the mp3 file, by making variables out of the names.

    This assumes you have your music library structured in a certain way. I use this structure:
    ///-.wav

    An example:
    /Rory Gallagher/Tattoo/01-Tattoo'd Lady.wav

    Code:
    #!/bin/bash
    
    # This is a script to transcode wave audio files (.wav) to .mp3, using ffmpeg.
    # It will also tag the .mp3 files, using the existing folder name and file name.
    # As a bonus, it will also create a .pls playlist in the folder containing the mp3 files.
    # It uses these programs, which you first must install:
    #
    # ffmpeg
    # id3ren
    # fapg
    #
    #
    # This script will only work correctly if you have your music arranged in folders like this:
    # ///-.wav
    #
    # An example:
    # /Rory Gallagher/Tattoo/01-Tattoo'd Lady.wav
    #
    #
    # Create two functions to make the $ALBUM and $ARTIST variables, and run them:
    
    echo
    function ALBUM {
    ALBUM=`basename "$PWD"`
    echo "Album = $ALBUM"
    sleep 3s
    }
    
    ALBUM
    
    # Go up one level in the directory, to get the name of the Artist:
    
    cd ..
    
    echo
    function ARTIST {
    ARTIST=`basename "$PWD"`
    echo "Artist = $ARTIST"
    sleep 3s
    }
    
    ARTIST
    echo
    echo
    
    # Go back to the previous folder:
    
    cd "$OLDPWD"
    
    # Replace spaces with underscores:
    # dirty hack to make spaces in file names work
    oldifs=$IFS; #IFS= Internal Field Separator
    IFS=_
    
    # Convert wave files in current directory to mp3 files.
    # Make a new folder mp3 using the name of the current folder,
    # and move the mp3 files to that folder.
    
    for i in *.wav; do mv "$i" `echo $i | tr ' ' '_'`; ffmpeg -i $i -ab 320k -acodec libmp3lame ${i%.wav}.mp3; mkdir "$ALBUM-mp3"; mv *.mp3 "$ALBUM-mp3"; done
    
    
    cd "$ALBUM-mp3"
    
    # Tag files using id3ren:
    
    id3ren -tagonly -tagfromfilename -tagtemplate '%n-%s.mp3' -nocomment -noyear -album="$ALBUM" -genre=12  -artist="$ARTIST" *.mp3
    
    # Make a playlist using fapg
    
    fapg --format=pls --output="$ALBUM".pls "$PWD"
    
    # Undo hack from above.
    IFS=$oldifs;
    My files are in a main folder named "Music", but I first 'cd' into the folder that I am going to transcode into mp3.
    Please do not send Private Messages to me with requests for help. I will not reply.

  7. #7
    Just Joined!
    Join Date
    Jan 2014
    Posts
    7
    Quote Originally Posted by gregm View Post
    Now it's getting ugly
    Code:
    for f in /data/music/**/*.m4a; do mkdir $(dirname $(echo $f | sed s/alac/flac/)); avconv -i "$f" "$(echo ${f%.m4a}.flac | sed s/alac/flac/)"; done
    (untested)
    close but not close.

    That ends up trying to create
    Code:
    . . . . [flac] .

  8. #8
    Linux Engineer
    Join Date
    Dec 2013
    Posts
    1,294
    Hmm.

    What is the output from:
    Code:
    for f in /data/music/**/*.m4a; do echo $(dirname $(echo $f | sed s/alac/flac/)); done

  9. #9
    Just Joined!
    Join Date
    Jan 2014
    Posts
    7
    Code:
    aaron@aaDesktop:$ ll
    total 24
    drwxr-xr-x  4 aaron aaron 4096 Jan  2 09:40 .
    drwxr-xr-x 39 aaron aaron 4096 Jan  2 09:26 ..
    drwx--x--x  2 aaron aaron 4096 Jan  1 20:22 Aphex Twin - Classics [alac]
    
    [~/test]
    aaron@aaDesktop:$ for f in /home/aaron/test/**/*.m4a; do echo $(dirname $(echo $f | sed s/alac/flac/)); done
    /home/aaron/test . . . [flac] .

  10. #10
    Linux Engineer
    Join Date
    Dec 2013
    Posts
    1,294
    Spaces in directory or file names are evil. They are permitted in Linux - even though they are a bad idea, clearly illustrated here.

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •