Bash file "if exist" and looping question - Questions

This is a discussion on Bash file "if exist" and looping question - Questions ; The following is a VERY naive way to accomplish "if any files in a pattern exist" do some stuff with them. Please suggest the best place to ask such questions, good web sources for learning Linux/bash/etc scripting, and how to ...

+ Reply to Thread
Results 1 to 12 of 12

Thread: Bash file "if exist" and looping question

  1. Bash file "if exist" and looping question

    The following is a VERY naive way to accomplish "if any
    files in a pattern exist" do some stuff with them.

    Please suggest the best place to ask such questions, good
    web sources for learning Linux/bash/etc scripting, and
    how to do this 'right' (or at least better):

    #!/usr/bin/sh
    for A in /etc/mail/move/*; do
    if [ -f ${A} ] ; then
    echo Do something with $A
    echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    fi
    done
    ###############end##################


    When I tried the (more) naive method of merly testing on
    [ -f /etc/mail/move/* ] there were errors (only) when the files
    existed.

    FYI: This was run on Cygwin if it matters.

    --
    Herb Martin



  2. Re: Bash file "if exist" and looping question

    On 2005-07-06, Herb Martin wrote:
    > The following is a VERY naive way to accomplish "if any
    > files in a pattern exist" do some stuff with them.
    >
    > Please suggest the best place to ask such questions, good
    > web sources for learning Linux/bash/etc scripting, and
    > how to do this 'right' (or at least better):


    Try the comp.unix.shell newsgroup.

    > #!/usr/bin/sh
    > for A in /etc/mail/move/*; do
    > if [ -f ${A} ] ; then
    > echo Do something with $A
    > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    > fi
    > done
    > ###############end##################


    That is a good way to do it, but it could be a little faster like
    this:

    set -- /etc/mail/move/*
    [ -f "$1" ] &&
    for A
    do
    echo Do something with $A
    echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    done

    > When I tried the (more) naive method of merly testing on
    > [ -f /etc/mail/move/* ] there were errors (only) when the files
    > existed.


    That fails because the shell expands the wild card, and the
    resulting command looks something like:

    [ -f /etc/mail/move/abc /etc/mail/move/def /etc/mail/move/ghi ]

    There can only be one argument to -f, so you get an error.

    > FYI: This was run on Cygwin if it matters.


    --
    Chris F.A. Johnson
    ================================================== ================
    Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress


  3. Re: Bash file "if exist" and looping question

    On Wed, 06 Jul 2005 03:44:55 GMT, Herb Martin wrote:
    > The following is a VERY naive way to accomplish "if any
    > files in a pattern exist" do some stuff with them.


    find is another method to find files.


    > Please suggest the best place to ask such questions, good
    > web sources for learning Linux/bash/etc scripting, and
    > how to do this 'right' (or at least better):


    http://www.tldp.org/LDP/abs/html/index.html

    For debugging or see what is going on in a script, you can put

    set -xv # enable debugging

  4. Re: Bash file "if exist" and looping question


    "Chris F.A. Johnson" wrote in message
    news:622sp2-h74.ln1@rogers.com...
    > On 2005-07-06, Herb Martin wrote:
    > > The following is a VERY naive way to accomplish "if any
    > > files in a pattern exist" do some stuff with them.
    > >
    > > Please suggest the best place to ask such questions, good
    > > web sources for learning Linux/bash/etc scripting, and
    > > how to do this 'right' (or at least better):

    >
    > Try the comp.unix.shell newsgroup.


    Thanks.

    > > #!/usr/bin/sh
    > > for A in /etc/mail/move/*; do
    > > if [ -f ${A} ] ; then
    > > echo Do something with $A
    > > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    > > fi
    > > done
    > > ###############end##################

    >
    > That is a good way to do it, but it could be a little faster like
    > this:


    I wasn't worried much about speed but my method seemed incredibly
    ugly -- and it would run slow if there were a thousand files since
    the commands were going to operate on all files the first time and the
    "for" was really gratuitious -- just a sneaky way to do something if
    any existed.

    > set -- /etc/mail/move/*
    > [ -f "$1" ] &&
    > for A
    > do
    > echo Do something with $A
    > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    > done
    >


    I don't understand the "set --" in this context nor how it
    plays with the testing of -f but it looks simple enough....

    Thanks again.

    I found this free 600+ page tutorial:

    http://www.tldp.org/LDP/abs/abs-guide.pdf

    --
    Herb Martin



  5. Re: Bash file "if exist" and looping question

    On 2005-07-06, Herb Martin wrote:
    >
    > "Chris F.A. Johnson" wrote in message
    > news:622sp2-h74.ln1@rogers.com...
    >> On 2005-07-06, Herb Martin wrote:
    >> > The following is a VERY naive way to accomplish "if any
    >> > files in a pattern exist" do some stuff with them.

    [snip]
    >> > #!/usr/bin/sh
    >> > for A in /etc/mail/move/*; do
    >> > if [ -f ${A} ] ; then
    >> > echo Do something with $A
    >> > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    >> > fi
    >> > done
    >> > ###############end##################

    >>
    >> That is a good way to do it, but it could be a little faster like
    >> this:

    >
    > I wasn't worried much about speed but my method seemed incredibly
    > ugly -- and it would run slow if there were a thousand files since
    > the commands were going to operate on all files the first time and the
    > "for" was really gratuitious -- just a sneaky way to do something if
    > any existed.


    It all depends on what you want to do with the files. If, for
    example, you just want to move them, there's no need for a loop:

    set -- /etc/mail/move/*
    [ -f "$1" ] && mv /etc/mail/move/* /etc/mail/oldspam/


    If you have to operate on each file individually, then you need
    the loop.

    >> set -- /etc/mail/move/*
    >> [ -f "$1" ] &&
    >> for A
    >> do
    >> echo Do something with $A
    >> echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    >> done
    >>

    >
    > I don't understand the "set --" in this context nor how it
    > plays with the testing of -f but it looks simple enough....


    See the last two sentences from "help set".

    > I found this free 600+ page tutorial:
    >
    > http://www.tldp.org/LDP/abs/abs-guide.pdf


    I prefer the HTML version:




    --
    Chris F.A. Johnson
    ================================================== ================
    Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress


  6. Re: Bash file "if exist" and looping question

    > It all depends on what you want to do with the files. If, for
    > example, you just want to move them, there's no need for a loop:
    >
    > set -- /etc/mail/move/*
    > [ -f "$1" ] && mv /etc/mail/move/* /etc/mail/oldspam/
    >
    >
    > If you have to operate on each file individually, then you need
    > the loop.


    Right. The loop was the ugly kludge I introduced to test for the
    existence of ANY file matching the pattern -- all of my actions
    were possible on the WHOLE set at once (like move).

    FYI: I was SpamAssassin "learning" (sa-learn) a directory of
    files to either Ham or Spam, then moving them to an "old" (Ham
    or Spam) directory afterwards.

    The loop was 'stupid' -- but it was my method of checking for
    existence -- and this was my reason for asking you for a better
    way.

    After you showed me the "set --" syntax I found that in one of
    my books and have begun to understand it...

    The loop is gone -- thanks, it works with the set --; [-f "$1"]

    --
    Herb Martin



  7. Re: Bash file "if exist" and looping question

    Herb Martin wrote:
    >> It all depends on what you want to do with the files. If, for
    >> example, you just want to move them, there's no need for a loop:
    >>
    >>set -- /etc/mail/move/*
    >>[ -f "$1" ] && mv /etc/mail/move/* /etc/mail/oldspam/
    >>
    >>
    >> If you have to operate on each file individually, then you need
    >> the loop.

    >
    >
    > Right. The loop was the ugly kludge I introduced to test for the
    > existence of ANY file matching the pattern -- all of my actions
    > were possible on the WHOLE set at once (like move).
    >
    > FYI: I was SpamAssassin "learning" (sa-learn) a directory of
    > files to either Ham or Spam, then moving them to an "old" (Ham
    > or Spam) directory afterwards.
    >
    > The loop was 'stupid' -- but it was my method of checking for
    > existence -- and this was my reason for asking you for a better
    > way.
    >
    > After you showed me the "set --" syntax I found that in one of
    > my books and have begun to understand it...
    >
    > The loop is gone -- thanks, it works with the set --; [-f "$1"]
    >


    If all you're doing is moving every file in /etc/mail/move you really don't
    need the test; e.g.,

    mv /etc/mail/move/* /etc/mail/oldspam/ 2>/dev/null

    /dan

  8. Re: Bash file "if exist" and looping question

    > > The loop is gone -- thanks, it works with the set --; [-f "$1"]
    > >

    >
    > If all you're doing is moving every file in /etc/mail/move you really

    don't
    > need the test; e.g.,
    >
    > mv /etc/mail/move/* /etc/mail/oldspam/ 2>/dev/null


    I understand that but no, I was performing several commands
    (each one operating on the entire file set) and two of these
    commands had a relatively long startup time, so that I wanted
    to skip the set entirely if there were 0 files to process.

    Below is the actual final version (including my real paths which
    weren't relevant to the original question):

    #!/usr/bin/bash
    for TYPE in spam ham; do
    echo -n $TYPE...
    set -- /etc/mail/spamassassin/$TYPE/move/*
    [ -f "$1" ]
    && \
    sa-learn --forget --showdots /etc/mail/spamassassin/$TYPE/move/* &&
    \
    sa-learn --$TYPE --showdots /etc/mail/spamassassin/$TYPE/move/* && \
    mv /etc/mail/spamassassin/$TYPE/move/* /etc/mail/spamassassin/old$TYPE/
    echo done.
    done
    exit 0


    I have tools that move spam and ham messages into those ../$TYPE/move
    directories and this process ensures the mail is properly classified by
    SpamAssassin and then moved to the ./old$TYPE/ directory for archiving.

    Thanks to everyone who responded.

    --
    Herb



  9. Re: Bash file "if exist" and looping question

    Chris F.A. Johnson wrote:
    > On 2005-07-06, Herb Martin wrote:
    > > The following is a VERY naive way to accomplish "if any
    > > files in a pattern exist" do some stuff with them.
    > >
    > > Please suggest the best place to ask such questions, good
    > > web sources for learning Linux/bash/etc scripting, and
    > > how to do this 'right' (or at least better):

    >
    > Try the comp.unix.shell newsgroup.
    >
    > > #!/usr/bin/sh
    > > for A in /etc/mail/move/*; do
    > > if [ -f ${A} ] ; then
    > > echo Do something with $A
    > > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    > > fi
    > > done
    > > ###############end##################

    >
    > That is a good way to do it, but it could be a little faster like
    > this:


    Can you elaborate on this? They look the same to me, same glob
    expansion and same test.

    >
    > set -- /etc/mail/move/*
    > [ -f "$1" ] &&
    > for A
    > do
    > echo Do something with $A
    > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    > done


    --
    William Park , Toronto, Canada
    ThinFlash: Linux thin-client on USB key (flash) drive
    http://home.eol.ca/~parkw/thinflash.html
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  10. Re: Bash file "if exist" and looping question

    On 2005-07-17, William Park wrote:
    > Chris F.A. Johnson wrote:
    >> On 2005-07-06, Herb Martin wrote:
    >> > The following is a VERY naive way to accomplish "if any
    >> > files in a pattern exist" do some stuff with them.
    >> >
    >> > Please suggest the best place to ask such questions, good
    >> > web sources for learning Linux/bash/etc scripting, and
    >> > how to do this 'right' (or at least better):

    >>
    >> Try the comp.unix.shell newsgroup.
    >>
    >> > #!/usr/bin/sh
    >> > for A in /etc/mail/move/*; do
    >> > if [ -f ${A} ] ; then
    >> > echo Do something with $A
    >> > echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    >> > fi
    >> > done
    >> > ###############end##################

    >>
    >> That is a good way to do it, but it could be a little faster like
    >> this:

    >
    > Can you elaborate on this? They look the same to me, same glob
    > expansion and same test.


    In the above script test is called for every file. In mine, below,
    it is only called once.

    >> set -- /etc/mail/move/*
    >> [ -f "$1" ] &&
    >> for A
    >> do
    >> echo Do something with $A
    >> echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    >> done

    >



    --
    Chris F.A. Johnson
    ================================================== ================
    Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress


  11. Re: Bash file "if exist" and looping question

    On Mon, 18 Jul 2005 16:16:36 -0400, "Chris F.A. Johnson" wrote:
    > On 2005-07-17, William Park wrote:
    > > Chris F.A. Johnson wrote:

    ....
    > > Can you elaborate on this? They look the same to me, same glob
    > > expansion and same test.

    >
    > In the above script test is called for every file. In mine, below,
    > it is only called once.
    >
    > >> set -- /etc/mail/move/*
    > >> [ -f "$1" ] &&

    ^^^^^^^^^^^^^^--> isn't this a redundant test? Obfuscation?
    > >> for A
    > >> do
    > >> echo Do something with $A
    > >> echo And: mv /etc/mail/move/* /etc/mail/oldspam/
    > >> done

    Grant.


  12. Re: Bash file "if exist" and looping question

    G_r_a_n_t_@dodo.com.au wrote:
    > On Mon, 18 Jul 2005 16:16:36 -0400, "Chris F.A. Johnson" wrote:
    >
    >>On 2005-07-17, William Park wrote:
    >>
    >>>Chris F.A. Johnson wrote:

    >
    > ...
    >
    >>>Can you elaborate on this? They look the same to me, same glob
    >>>expansion and same test.

    >>
    >> In the above script test is called for every file. In mine, below,
    >> it is only called once.
    >>
    >>
    >>>>set -- /etc/mail/move/*
    >>>>[ -f "$1" ] &&

    >
    > ^^^^^^^^^^^^^^--> isn't this a redundant test? Obfuscation?



    No, because the set might get nothing at all - empty dir or maybe even
    no such directory at all.


    --
    Tony Lawrence
    Unix/Linux/Mac OS X resources: http://aplawrence.com

+ Reply to Thread