Find the answer to your Linux question:
Results 1 to 9 of 9
Like Tree1Likes
  • 1 Post By alf55
Hi all, I'm new to scripting, I know linux scripting is very powerful. This is what I want to accomplish: 1. read the files in a directory. 2. If it ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Feb 2014
    Location
    Houston, TX
    Posts
    5

    Help with script organizing directory


    Hi all,

    I'm new to scripting, I know linux scripting is very powerful.
    This is what I want to accomplish:
    1. read the files in a directory.
    2. If it finds files with extensions .mkv .iso .mp4, create a directory with the name of the file (obviously withoiut the extension)
    3. move any file that contains that name regardless of the extension (some files will also contain .srt or .sup into the newly created directory

    what I've done:

    I try to accomplish item 1 with this command in my script, but I run into a problem right away, which I'll explain here
    -but, when i run
    Code:
    ls | grep -v ^d | egrep "mkv|iso|mp4"
    at the command prompt I get this:

    Willy Wonka and the Chocolate Factory.mkv
    Winnie the Pooh 2011.mkv

    - when i run
    Code:
    #!/bin/bash
    for FILE in `ls | grep -v ^d | egrep "mkv|iso|mp4"`
    do
    echo $FILE
    done
    I get this (one word per line):
    Willy
    Wonka
    and
    the
    Chocolate
    Factory.mkv
    Winnie
    the
    Pooh
    2011.mkv

    ---
    This line in my code
    Code:
    DIR=(echo $FILE | sed 's/.mp4//')
    is trying to create the directory name and strip the extension, I was trying to see if i could do this with the 3 extension in the same line, something like
    Code:
    DIR=(echo $FILE | sed 's/[.mp4] [.mkv] [.iso]//'
    but I couldn't find it, thus, I left it with just .mp4

    ---
    Finally, I can't figure out how to move the files that contain *.srt and *.sup to be moved to the newly created directory
    example: Willy Wonka and the Chocolate Factory.srt

    ---
    So here is my non-accomplishing script:
    Code:
    #!/bin/bash
    for FILE in `ls | grep -v ^d | egrep "mkv|iso|mp4"`
    do
      DIR=(echo $FILE | sed 's/.mp4//') 
      mkdir -p $DIR
    mv $FILE $DIR
    done
    Thank you all for your help

  2. #2
    Linux Engineer docbop's Avatar
    Join Date
    Nov 2009
    Location
    Woodshed, CA
    Posts
    949
    Seems like someone asked an almost identical questions a few months ago, is this a homework assignment from a class? Only difference I think they were doing music and your doing movies.

    If you search you might find the previoius post it was about taking filename and creating directories based on the names.

  3. #3
    Just Joined!
    Join Date
    Feb 2014
    Location
    Houston, TX
    Posts
    5
    no, my is real need. I'll look for the thread.
    Thanks!

  4. $spacer_open
    $spacer_close
  5. #4
    Just Joined!
    Join Date
    Feb 2014
    Location
    Houston, TX
    Posts
    5
    I was unable to find the mentioned thread. I'm still trying to find a solution to my problem

  6. #5
    Linux User nihili's Avatar
    Join Date
    Dec 2013
    Posts
    346
    some pseudo-code to help you get going:
    Code:
    cd /dir/where/your/files/are
    
    for file in * 
    do
        if files last 4 chars are .mkv
               (do things)
        fi
        if files last 4 chars are .iso
        .....and so on, you get the picture
    done
    ps: i've written whole shell scripts with the help of web searches, usually prepending bash or sed to my search.
    sites like stackoverflow are FULL of helpful stuff.

  7. #6
    Just Joined!
    Join Date
    Feb 2014
    Location
    Houston, TX
    Posts
    5
    Quote Originally Posted by nihili View Post
    some pseudo-code to help you get going:
    Code:
    cd /dir/where/your/files/are
    
    for file in * 
    do
        if files last 4 chars are .mkv
               (do things)
        fi
        if files last 4 chars are .iso
        .....and so on, you get the picture
    done
    ps: i've written whole shell scripts with the help of web searches, usually prepending bash or sed to my search.
    sites like stackoverflow are FULL of helpful stuff.
    Thanks for your help!!

    I ended up doing it this way


    Code:
    #!/bin/bash
    dir="/media/external/movies"
    if [[ `ls | grep -c mp4` == 0 ]]
    then
            echo "NO MOVIE FILES"
    else
            for f in *.mp4
            do
                    d=$(echo $f | sed 's/.mp4//')
                    mkdir -p "$dir/$d/"
                    mv -u "$f" "$dir/$d"
                    mv -u "$d.srt"  "$dir/$d"
                    mv -u "$d.sup"  "$dir/$d"
            done
    fi
    
    if [[ `ls | grep -c mkv` == 0 ]]
    then
            echo "NO MOVIE FILES"
    else
            for f in *.mkv
            do
                    d=$(echo $f | sed 's/.mkv//')
                    mkdir -p "$dir/$d/"
                    mv -u "$f" "$dir/$d"
                    mv -u "$d.srt"  "$dir/$d"
                    mv -u "$d.sup"  "$dir/$d"
            done
    fi
    
    if [[ `ls | grep -c iso` == 0 ]]
    then
            echo "NO MOVIE FILES"
    else
            for f in *.iso
            do
                    d=$(echo $f | sed 's/.iso//')
                    mkdir -p "$dir/$d/"
                    mv -u "$f" "$dir/$d"
                    mv -u "$d.srt"  "$dir/$d"
                    mv -u "$d.sup"  "$dir/$d"
            done
    fi

  8. #7
    Linux Newbie
    Join Date
    Nov 2009
    Posts
    238
    The reason your echo $FILE" is showing you each word separately is because the variable $FILE contains an array of "tokens" as per those listed on your command line version. Each "token" is separated by a space.

    I agree with doc here, sounds like homework again.

    Have a look at awk unless the assignment specifically forbids you to.

  9. #8
    Just Joined!
    Join Date
    Feb 2014
    Location
    Houston, TX
    Posts
    5
    Quote Originally Posted by voidpointer69 View Post
    The reason your echo $FILE" is showing you each word separately is because the variable $FILE contains an array of "tokens" as per those listed on your command line version. Each "token" is separated by a space.

    I agree with doc here, sounds like homework again.

    Have a look at awk unless the assignment specifically forbids you to.

    voidpointer69, I wish it was homework, that'd mean that I'm going to school. So, there is no rules.

    Like I mentioned in my last post, I solved the issue with the code posted there . I had about 800 files to process, that's why I wanted automation.
    The code that solved my issue was a little ugly on the execution because not all the files had *.sup or *.srt files, so I had a lot of errors stating that there were no files to be moved, but after all said and done, the directories were created and my files moved into the directories just as I wanted.
    Now, for the benefit of others, how can this script be made better?

  10. #9
    Linux Enthusiast
    Join Date
    Jan 2005
    Location
    Saint Paul, MN
    Posts
    673
    The problem is that Linux allows lots to characters in file names that cause issues for script handling (most used is a space character). Rather and tell you how to do this task, I will show you how to learn what to do:

    Code:
    # test case generation:
    mkdir /tmp/funny_file_names
    cd    /tmp/funny_file_names 
    touch my\ file  `filename \[filename\] \{filename\} my\>file my\>file my\|file my\&file my\!file my\'file my\"file my\file
    
    # From http://www.linuxforums.org/forum/members/watael.html on posting
    # at http://www.linuxforums.org/forum/programming-scripting/199333-pass-filename-variable-shell-script.html
    # at bottom of page 1.
    
    ar=() ; while IFS= read -d '' -r f; do ar+=( "$f" ); done < <(find ./ -type f -print0)
    
    # or my first modifacation of above:
    
    ar=( $( while IFS= read -d '' -r f; do echo "$f" ; done < <(find ./ -type f -print0) ) )
    
    # or  my second modification of above:
    
    ar=( $(find ./ -type f -print0 | while IFS= read -d '' -r f; do echo "$f" ; done) )
    Using the array:
    Code:
    for filename in "${ar[@]}"; do
       echo "${filename}"
    done
    voidpointer69 likes this.

Posting Permissions

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