ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
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:
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
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.
#!/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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.