Results 1 to 7 of 7
I have very little linux experience. And need some help with a bash script. I need to a script I can set cron to run to sort files out of ...
- 09-28-2010 #1Just Joined!
- Join Date
- Mar 2010
- Posts
- 3
[SOLVED] Bash Script; Sort files into directory based on data in the file name
I have very little linux experience. And need some help with a bash script. I need to a script I can set cron to run to sort files out of a holding folder into final folders.
It doesn't necessarily have to be bash, but I think it would be sufficient for this.
File names are formatted as such when created: Dest-Date-Time-CID-Destination#
I want the files to be moved from a all in one holding folder to a folder structure like this.
.../storage/year/month/day/Destination#/VarX(type)/hour/CID/'File'
I would need an if/else if/else statement to say if Dest = A set VarX = B
If for example the file name was
infinity-20100927-17:00-1112223333-4445556666.wav
I would like the above file to end up moved from
.../holding
to
.../storage/2010/09/27/4445556666/Inbound/17/1112223333/infinity-20100927-17:00-1112223333-4445556666.wav
So the script will need to make directories based on information in the file name which is delimited by single dashes. Then move files from the holding folder to the newly created "sorted" folders.
Thank You for your time and help.
- 09-28-2010 #2
I think a script with ls, grep and sed in a for loop should do the job pretty well.
- 09-29-2010 #3Just Joined!
- Join Date
- Sep 2007
- Posts
- 6
awk maybe
Try something like:
ls -1 | gawk -F"-" '{
if (something = other-thing )
do nonsense;
system("mv " $0 " <Fixed part of path>/" sub($2,1,4)"/"..."/"$5 etc)
}'
- 09-29-2010 #4Just Joined!
- Join Date
- Mar 2007
- Posts
- 5
Something like this should do it:-
You could add more validation tests I suppose but this works for the case you give in your example. Also - is the 'Inbound' part of your storage directory always a constant?Code:#!/bin/bash # Set these two variables to the full pathname # of your holding and storage directories holding=/tmp/MTAS/holding storage=/tmp/MTAS/storage cd $holding for file in $(ls -A) do echo $file Dest=$(echo $file | cut -d'-' -f 1) Date=$(echo $file | cut -d'-' -f 2) Time=$(echo $file | cut -d'-' -f 3) CID=$(echo $file | cut -d'-' -f 4) Destination=$(echo $file | cut -d'-' -f 5 | cut -d'.' -f 1) year=${Date:0:4} month=${Date:4:2} day=${Date:6:2} hour=${Time:0:2} storage_dir=$storage/$year/$month/$day/$Destination/Inbound/$hour/$CID # Remove the -v for no confirmation of directory creation if [ ! -d $storage_dir ] then mkdir -v -p $storage_dir fi # Remove the -v for no confirmation of file movement mv -v $file $storage_dir done
- 09-30-2010 #5Linux User
- Join Date
- Jan 2005
- Location
- Saint Paul, MN
- Posts
- 262
How about only in bash... no sed, grep, cut, etc ...
Assuming the file name is the variable, name, look at this example...
show testing example:Code:ext="${name##*\.}" parts=( $( IFS='-' && echo ${name%\.${ext}} ) ) the_date="${parts[1]}" dest="${parts[0]}" year="${the_date:0:4}" month="${the_date:4:2}" day="${the_date:6:2}" time="${parts[2]}" cid="${parts[3]}" destination="${parts[4]}" mv .../holding/${name} .../storage/${year}/${month}/${day}/${time}/Inbound/${time:0:2}/${cid}/${name}
which produces the output:Code:function testing { name="$1" ext="${name##*\.}" parts=( $( IFS='-' && echo ${name%\.${ext}} ) ) the_date="${parts[1]}" dest="${parts[0]}" year="${the_date:0:4}" month="${the_date:4:2}" day="${the_date:6:2}" time="${parts[2]}" cid="${parts[3]}" destination="${parts[4]}" echo mv .../holding/${name} .../storage/${year}/${month}/${day}/${time}/Inbound/${time:0:2}/${cid}/${name} } testing infinity-20100927-17:00-1112223333-4445556666.wav
Code:mv .../holding/infinity-20100927-17:00-1112223333-4445556666.wav .../storage/2010/09/27/17:00/Inbound/17/1112223333/infinity-20100927-17:00-1112223333-4445556666.wav
Last edited by alf55; 09-30-2010 at 04:09 AM. Reason: Changed function to pass in the name as argument 1
- 09-30-2010 #6Just Joined!
- Join Date
- Mar 2010
- Posts
- 3
Asked on another forum and got some quicker responses yesterday. This is my "finished" script I'm actively using now. but it isn't fine tuned yet for instance going to replaceCode:#!/bin/bash for file in $(ls) do set $(echo $file | awk -F- '{print $1, $2, $3, $4, $5}') filestart=$1 fullyear=$2 fulltime=$3 aftertimesub=$4 suffix=$5 year=$(echo $fullyear |cut -c1-4) month=$(echo $fullyear |cut -c5-6) day=$(echo $fullyear |cut -c7-8) hour=$(echo $fulltime |awk -F: '{print $1}') suffixsubdir=$(echo $suffix |awk -F\. '{print $1}') if [ $1 == "infinity" ]; then typeX="Inbound" else if [ $1 == "bellout" ]; then typeX=Outbound else if [ $1 == "sipout" ]; then typeX=Outbound else if [ $1 == "PersonalLine" ]; then typeX=Inbound else typeX=Unknown fi fi fi fi type=$typeX newdir=$(echo /etc/test/Store/$year/$month/$day/$suffixsubdir/$type/$hour/) if ! [ -d $newdir ] then echo Directory $newdir does not exist. Creating same. mkdir -p $newdir fi mv $file $newdir done
example changing to
for file in * instead of for file in $(ls)
and moving to using case instead of nested Ifs
but Thank You for the help anyway
- 09-30-2010 #7Just Joined!
- Join Date
- Mar 2010
- Posts
- 3
Final Code
Code:#!/bin/bash for file in *.wav *.mp3 ; do set $(echo $file | awk -F- '{print $1, $2, $3, $4, $5}') filestart=$1 fullyear=$2 fulltime=$3 aftertimesub=$4 suffix=$5 year=$(echo $fullyear |cut -c1-4) month=$(echo $fullyear |cut -c5-6) day=$(echo $fullyear |cut -c7-8) hour=$(echo $fulltime |awk -F: '{print $1}') suffixsubdir=$(echo $suffix |awk -F\. '{print $1}') case $filestart in "infinity")type=Inbound;; "bellout")type=Outbound;; "sipout")type=Outbound;; "PersonalLine")type=Inbound;; "mili")type=Outbound;; *)type=Unknown;; esac newdir=$(echo /var/Store/$year/$month/$day/$type/$suffixsubdir/$hour/) if ! [ -d $newdir ] then echo Directory $newdir does not exist. Creating same. mkdir -p $newdir fi mv $file $newdir done


