LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-17-2012, 04:52 AM   #1
cbing
LQ Newbie
 
Registered: Apr 2012
Location: /root
Distribution: RHEL, CentOS, Fedora
Posts: 17

Rep: Reputation: Disabled
Bash script to move files from date


Hello.

I'm trying to make a bash script to move multiple files to different folders depending on the date.
The files structure is YYYY-MM-DD-name.
I want to move the files based on the year and month, but not the system, creation or modification date, I want the date of the filename. If the destination folders do not exist, the script will create it.

I've tried this script from David the H. (Thank's David ), and I've added the variable DATE=$(date +%Y) to the path of mkdir and mv.
Now I have the structure I want, but based on the current year.
How I can do to get the year of the filename?

Thanks.
 
Old 04-17-2012, 05:52 AM   #2
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 757

Rep: Reputation: 145Reputation: 145
Code:
year=${file:0:4}
 
Old 04-17-2012, 06:29 AM   #3
cbing
LQ Newbie
 
Registered: Apr 2012
Location: /root
Distribution: RHEL, CentOS, Fedora
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by KenJackson View Post
Code:
year=${file:0:4}
Thanks KenJackson.

This is what I was making, without success.

This is my script (copied from David_the_H.).

Code:
#!/bin/bash

DIR=/home/data/
target=$DIR
cd "$DIR"
year=${file:0:4}

for file in *; do

     case "${file:5:2}" in
          01)  mkdir -vp $target/$year/01_Jan
               mv -v -t $target/$year/01_Jan $file
               ;;
          02)  mkdir -vp $target/$year/02_Feb
               mv -v -t $target/$year/02_Feb $file
               ;;
          03)  mkdir -vp $target/$year/03_Mar
               mv -v -t $target/$year/03_Mar $file
               ;;
          04)  mkdir -vp $target/$year/04_Apr
               mv -v -t $target/$year/04_Apr $file
               ;;
          05)  mkdir -vp $target/$year/05_May
               mv -v -t $target/$year/05_May $file
               ;;
          06)  mkdir -vp $target/$year/06_Jun
               mv -v -t $target/$year/06_Jun $file
               ;;
          07)  mkdir -vp $target/$year/07_Jul
               mv -v -t $target/$year/07_Jul $file
               ;;
          08)  mkdir -vp $target/$year/08_Aug
               mv -v -t $target/$year/08_Aug $file
               ;;
          09)  mkdir -vp $target/$year/09_Sep
               mv -v -t $target/$year/09_Sep $file
               ;;
          10)  mkdir -vp $target/$year/10_Oct
               mv -v -t $target/$year/10_Oct $file
               ;;
          11)  mkdir -vp $target/$year/11_Nov
               mv -v -t $target/$year/11_Nov $file
               ;;
          12)  mkdir -vp $target/$year/12_Dec
               mv -v -t $target/$year/12_Dec $file
               ;;
          
        esac
  
done

exit 0
With this script, I get the files in different folders sorted by month (01_Jan, 02_Feb...), but not under its year.

Thanks.
 
Old 04-17-2012, 06:33 AM   #4
cbing
LQ Newbie
 
Registered: Apr 2012
Location: /root
Distribution: RHEL, CentOS, Fedora
Posts: 17

Original Poster
Rep: Reputation: Disabled
My fault.

This

Code:
year=${file:0:4}
should go after

Code:
for file in *; do
Thanks.
 
Old 04-17-2012, 07:24 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Glad to see my old code helped out.

Incidentally, with the mad coding skillz I've developed since that last post , I'd now recommend adding a function to reduce the complexity of it a bit.

Also, variable expansions should always be quoted, for safety and consistency.

Code:
#!/bin/bash

DIR=/home/data/
target=$DIR
cd "$DIR"

movefile(){

     # $1 is the target directory to create, $2 is the file to move into it
     mkdir -vp "$1"
     mv -v -t "$1" "$2"

}

for file in *; do

     year=${file:0:4}

     case "${file:5:2}" in
          01)  movefile "$target/$year/01_Jan" "$file" ;;
          02)  movefile "$target/$year/02_Feb" "$file" ;;
          03)  movefile "$target/$year/03_Mar" "$file" ;;
          04)  movefile "$target/$year/04_Apr" "$file" ;;
          05)  movefile "$target/$year/05_May" "$file" ;;
          06)  movefile "$target/$year/06_Jun" "$file" ;;
          07)  movefile "$target/$year/07_Jul" "$file" ;;
          08)  movefile "$target/$year/08_Aug" "$file" ;;
          09)  movefile "$target/$year/09_Sep" "$file" ;;
          10)  movefile "$target/$year/10_Oct" "$file" ;;
          11)  movefile "$target/$year/11_Nov" "$file" ;;
          12)  movefile "$target/$year/12_Dec" "$file" ;;
     esac

done

exit 0

FYI, There are quite a few techniques you can use for extracting substrings from variables like this. Check out these links:

parameter substitution
string manipulation
 
1 members found this post helpful.
Old 04-17-2012, 08:37 AM   #6
cbing
LQ Newbie
 
Registered: Apr 2012
Location: /root
Distribution: RHEL, CentOS, Fedora
Posts: 17

Original Poster
Rep: Reputation: Disabled
Thanks again David the H..

Your scripts have helped me a lot.

And of course, thanks for your links. (Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime).
 
Old 04-17-2012, 10:50 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
I thought you might be interested in seeing an even more compact version I thought up. It uses an array and a small bit of mathematic manipulation to eliminate the need for a case statement.

Code:
#!/bin/bash

DIR=/home/data
target=$DIR
cd "$DIR"

month=( 01_Jan 02_Feb 03_Mar 04_Apr 05_May 06_Jun
	07_Jul 08_Aug 09_Sep 10_Oct 11_Nov 12_Dec )

for file in *; do

	dname="$target/${file:0:4}/${month[10#${file:5:2} -1]}"
	mkdir -vp "$dname"
	mv -vt "$dname" "$file"

done

exit 0
 
Old 04-17-2012, 11:13 AM   #8
cbing
LQ Newbie
 
Registered: Apr 2012
Location: /root
Distribution: RHEL, CentOS, Fedora
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by David the H. View Post
I thought you might be interested in seeing an even more compact version I thought up. It uses an array and a small bit of mathematic manipulation to eliminate the need for a case statement.

Code:
#!/bin/bash

DIR=/home/data
target=$DIR
cd "$DIR"

month=( 01_Jan 02_Feb 03_Mar 04_Apr 05_May 06_Jun
	07_Jul 08_Aug 09_Sep 10_Oct 11_Nov 12_Dec )

for file in *; do

	dname="$target/${file:0:4}/${month[10#${file:5:2} -1]}"
	mkdir -vp "$dname"
	mv -vt "$dname" "$file"

done

exit 0
Great!!

Very good examples. I like to learn different ways to reach the same place.

Thanks.
 
Old 04-19-2012, 07:31 AM   #9
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
And just for fun:

Code:
#!/bin/bash

DIR=/home/data
target=$DIR
cd "$DIR"

for file in *; do

	dname="$( date -d "${file%-*}" "+$target/%Y/%m_%b" )"
	mkdir -vp "${dname%/*}"
	mv -vt "$dname" "$file"

done
This one is actually quite a bit slower than the previous versions, however, due to the dependency on the external date program. But hey, it's short!

Last edited by David the H.; 04-19-2012 at 07:32 AM. Reason: small code change
 
Old 04-20-2012, 05:45 AM   #10
cbing
LQ Newbie
 
Registered: Apr 2012
Location: /root
Distribution: RHEL, CentOS, Fedora
Posts: 17

Original Poster
Rep: Reputation: Disabled
Thanks David.

Awesome examples.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash script to move files except the last 5 dappa Linux - Newbie 4 08-26-2011 02:01 PM
[SOLVED] Bash script: how to move files to Trash instead of deleting? KonfuseKitty Programming 1 07-10-2010 12:44 PM
[SOLVED] Bash script needed to move files to another folder. No_one_knows_me Linux - General 28 01-07-2010 10:29 PM
bash script to delete files / folders based on date and freespace nekawa Linux - Newbie 5 06-08-2009 09:00 PM
Bash script: Move files, ignore case Fredde87 Linux - Software 3 09-03-2008 03:34 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration