OT: Bash script help needed

Owen Townend bowbowbow at optushome.com.au
Fri Dec 21 01:31:46 UTC 2007


On Thu, 2007-12-20 at 12:17 -0500, Craig Puchta wrote:
> On Fri, 2007-12-21 at 02:06 +1100, Owen Townend wrote: 
> > Hey,
> >   A little script like this would do what you want assuming the naming
> > conventions as above.
> > 
> >   Go through it and make sure you understand what each part is doing and
> > edit it for your needs before you try running it.
> > 
> >   If you need to get more complex with the base names and paths look
> > into 'sed' and 'awk' instead of 'cut'.
> >   http://www.grymoire.com/Unix/Sed.html is a great sed tut.
> > 
> > #!/bin/sh
> > #
> > # Sort logs into folders.
> > # example log name "rdb-001-001.txt"
> > #
> > 
> > WORKINGDIR="/path/to/files"
> > BASEPATH="/path/to/new/dir"
> > 
> > for i in `ls $WORKINGDIR`; do
> >   basename=`echo $i | cut -c -7`
> >   # test for an existing directory
> >   if [ ! -d ${BASEPATH}/${basename} ]
> >     # create the new dir if needed.
> >     then mkdir -p ${BASEPATH}/${basename}
> >   fi
> > 
> >   # now move the file(s)
> >   mv ${WORKINGDIR}/${basename}* ${BASEPATH}/${basename}/
> > 
> > done
> > 
> > 
> > Let me know what you think.
> > This will need to be added to if your files aren't all in the same dir
> > at the moment or if there are spaces or strange characters in the names.
> > 
> > cheers,
> > Owen.
> 
> I changed:
> 
> WORKINGDIR="/path/to/files" 
> BASEPATH="/path/to/new/dir"
> 
> to:
> 
> WORKINGDIR="/home/eldergod/ziso"
> BASEPATH="/home/eldergod/ziso"
> 
> I kept getting "mv: cannot move `/home/eldergod/ziso/rdb-030' to a
> subdirectory of itself, `/home/eldergod/ziso/rdb-030/rdb-030'
> Although it seems to have worked. I also tried it with:
> 
> WORKINGDIR="/home/eldergod/ziso"
> BASEPATH="/home/eldergod/ztest"
> 
> and mv said it couldn't stat the directory, but it also seemed to have
> worked.
> This script more or less confuses me, I guess I need a good "bash
> scripting for dummies" book :)
> I'll keep messing with it and thanks for the help, I'm going to try
> the
> script that Nils sent now.
> 
> 

Hey

Found why it came up with the error it did. ${basename}* matches the
directory it just created. You wouldn't get the error if you were using
different source & destinations or you can get rid of the error by just
adding more criteria to the match, like a .txt extension like so:

   # now move the file(s)
   mv ${WORKINGDIR}/${basename}*.txt ${BASEPATH}/${basename}/

And maybe add a check for the destination directory too.
The error you described would come up if ztest didn't already exist, 
this would fix that.
I'm looking for (eg) /home/eldergod/ztest/rdb-001, and if it doesn't 
exist then create it and if necessary it's parent directories too 
(/home, /home/eldergod, /home/eldergod/ztest). When it tries to find
ztest/rdb-001 it will throw the error "can't stat"... etc because it can't
get into ztest to look for rdb-001, but the next command creates it, hence
the error only throwing once.

  if [ ! -d ${BASEPATH} -o ! -d ${BASEPATH}/${basename} ]
     # create the new dir if needed.
     then mkdir -p ${BASEPATH}/${basename}
  fi

Might also want to add a test to see if the file exists, as this is iterating
through all file names, but moving in bulk.

BTW, the [ ] is the command 'test' in short, common form. 'test -d /home' 
and '[ -d /home ]' are the same thing.
If you're new to CLI/scripting then 'apropos' (man -k) is your friend. It 
searches command names and descriptions of man pages. So if you think 
there should be a command to do something but you're not sure what it is, 
this is an easy way to look for it.

Oh, and I'll second the O'Reilly book recommendation. I haven't used it myself,
but I have friends who seem to like it.

This script, although longer than the other suggestion, is, I think, simpler to understand.
Nils' is a more elegant & robust solution though.

ps, end result of the above suggestions:

 #!/bin/sh
 #
 # Sort logs into folders.
 # example log name "rdb-001-001.txt"
 #
 
 WORKINGDIR="/home/eldergod/ziso"
 BASEPATH="/home/eldergod/ztest"
 
 for i in `ls $WORKINGDIR`; do
   # make sure the file exists (hasn't already been moved)
   if [ -e ${WORKINGDIR}/$i ] then
     basename=`echo $i | cut -c -7`
     # test for an existing directory
     if [ ! -d ${BASEPATH} -o ! -d ${BASEPATH}/${basename} ]
       # create the new dir if needed.
       then mkdir -p ${BASEPATH}/${basename}
     fi
     # now move the file(s)
     mv ${WORKINGDIR}/${basename}*.txt ${BASEPATH}/${basename}/
   fi 
 done


cheers,
Owen.





More information about the ubuntu-users mailing list