Results 1 to 8 of 8

Thread: Move prefix files to folder by bash script

  1. #1
    Join Date
    Nov 2008
    Location
    Earth
    Beans
    73
    Distro
    Ubuntu Development Release

    Move prefix files to folder by bash script

    Hi all,
    I want to create a script that can help me organize my pictures into some folder. I hope by create this script I can gain new knowledge of using bash shell scripts

    Here are the problem:

    Files examples
    Code:
    2011-12-29_10.37.40.JPG
    2011-12-29_10.37.41.JPG
    2012-01-02_00.56.59.JPG
    2012-01-02_15.52.18.JPG
    2012-01-02_15.52.19.JPG
    .......
    .......
    What I want to do is to put all files that start from YYYY-MM into the folder name YYYY_MM,
    as right now I do it manually by

    PHP Code:
    mkdir 2011_12 && mv 2011-122011_12
    mkdir 2012_01 && mv 2012-012012_01 
    As the beginner of bash scripts. I hope, somebody can help me..

    Thanks.

  2. #2
    Join Date
    Feb 2007
    Location
    Romania
    Beans
    Hidden!

    Re: Move prefix files to folder by bash script

    You can use GNU/find to find the file names:

    Code:
    find ./ -maxdepth 1 -regextype posix-extended -iregex '^\./[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}_.*.jpg'
    with its -printf option you can print only the YYYY-MM part of the file names:
    Code:
    find ./ -maxdepth 1 -regextype posix-extended -iregex '^\./[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}_.*.jpg' -printf '%.9p\n'
    Now you can pipe the output of find to GNU/sort or GNU/uniq in order to omit the repeated names:
    Code:
    find ./ ... | sort -u
    And finally you can redirect the output of the above pipeline to a while loop. In the loop you can create each directory and move the files:

    Code:
    #!/bin/bash
    
    # replace path/to/dir with an actual path
    cd path/to/dir || exit 1
    
    while IFS= read -r -d '' dir
    do
        mkdir -p "${dir//-/_}"
        mv -b -- "$dir"*.[jJ][pP][gG] "${dir//-/_}"
    done < <(find ./ -maxdepth 1 -regextype posix-extended -iregex '^\./[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}_.*.jpg' -printf '%.9p\0' | sort -zu)
    Please test the script before you use it. And keeping a backup of your data is always a good idea.
    Last edited by sisco311; April 4th, 2013 at 08:54 PM.

  3. #3
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Move prefix files to folder by bash script

    you can easily create all combinations of (years) and (months)

    Code:
    for mth in {2011..2013}-{01..12}
    do
      echo "$mth"
      mkdir -p "$mth"
      mv "$mth"*.[jJ][pP][gG] "$mth"
    done
    if you don't want to have tons of potentially empty directories you need to process files individually

    Code:
    for f in [0-9][0-9][0-9][0-9]-[0-9][0-9]-*.[jJ][pP][gG]
    do
      mkdir -p "${f:0:7}"
      mv "$f" "${f:0:7}"
    done
    Last edited by Vaphell; April 4th, 2013 at 09:00 PM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  4. #4
    Join Date
    Feb 2009
    Location
    Dallas, TX
    Beans
    7,790
    Distro
    Ubuntu 16.04 Xenial Xerus

    Re: Move prefix files to folder by bash script

    EDIT: I continue to be the slowest to reply... as usual.

    Hi safarin.

    First, you can cycle through all your images with something like this:
    Code:
    #!/bin/bash
    for file in *.JPG
    do
        echo "$file"
    done
    Note that this would only consider images ending in JPG.

    If you also have jpg, jpeg, and others, you would need to include it in the expression:
    Code:
    #!/bin/bash
    for f in *.JPG *.jpg *.jpeg
    do
        echo "$file"
    done
    Once you are sure you are getting all images in your loop, you can start using parameter substitution to get the directory part out of the filename.

    The following expression would get the directory as you wanted:
    Code:
    ${file%-[0-9][0-9]_*}
    You can test that by doing:
    Code:
    #!/bin/bash
    for file in *.JPG
    do
        echo "moving $file  -->  ${file%-[0-9][0-9]_*}"
    done
    But the directory does not exist yet. You could create it with the 'mkdir' command, but that would give you an error in subsequent intents to create the same directory. Testing if the directory exists would solve the problem.
    Code:
    #!/bin/bash
    for file in *.JPG
    do
        dir="${file%-[0-9][0-9]_*}"
    
        if [ ! -d "$dir" ]; then
            echo mkdir "$dir"
        fi
    
        echo mv -iv "$file"  "${file%-[0-9][0-9]_*}"
    done
    Now, if you feel you are ready to roll, remove both words echo on the script to actually create the directories and move the files.

    Hope it helps. Let us know how it goes.
    Regards.

    P.S: If you want to continue exploring study the following alternative skeleton for the cycle:
    Code:
    #!/bin/bash
    while IFS= read -r -d '' file
    do
        echo "$file"
    done < <(find . -maxdepth 1 -regex '.*jpg\|.*jpeg' -print0)

  5. #5
    Join Date
    Feb 2013
    Beans
    Hidden!

    Re: Move prefix files to folder by bash script

    Perhaps
    Code:
    ls -q|sed -nr 's/^([0-9]{4}-[0-9]{2}).*/\1/p'|uniq|xargs -rd\\n -n1 sh -c 'd=${0%-*}_${0#*-};mkdir -p $d&&mv $0* $d'
    Last edited by schragge; April 8th, 2013 at 08:30 PM.

  6. #6
    Join Date
    Feb 2007
    Location
    Romania
    Beans
    Hidden!

    Re: Move prefix files to folder by bash script

    On a second thought, you could use printf instead of find:
    Code:
    printf '%.9s\0' ./[[:digit:]][[:digit:]][[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]_*.[jJ][pP][gG] | sort -zu | while IFS= read -r -d '' dir; do echo "$dir"; done

    Quote Originally Posted by schragge View Post
    Perhaps
    Code:
    ls|sed -nr 's/^([0-9]{4}-[0-9]{2}).*/\1/p'|uniq|xargs -d\\n -n1 sh -c 'mkdir $0 && mv $0-* $0'
    It might work in this particular case, but parsing ls is considered a bad practice:
    http://mywiki.wooledge.org/ParsingLs

  7. #7
    Join Date
    Nov 2008
    Location
    Earth
    Beans
    73
    Distro
    Ubuntu Development Release

    Re: Move prefix files to folder by bash script

    Wow! I never thought the solution would be some complicated syntax code...
    Thank you guys.. I need extra time to study and experiment what does the codes do, because mostly it seem new to me.

    I will update to you guys later...
    Thanks~!!

  8. #8
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    2,172
    Distro
    Ubuntu 16.04 Xenial Xerus

    Re: Move prefix files to folder by bash script

    Something that can be read without the help of a whole jar of Aspirin pills:

    Code:
    for file in ????-??-??_??.??.??.JPG
    do
       dir=${file:0:4}_${file:5:2}
       mkdir -p $dir
       mv $file $dir
    done

Bookmarks

Posting Permissions

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