Operating System - HP-UX
1748060 Members
5622 Online
108758 Solutions
New Discussion

building dynamically a find command

 
SwissKnife
Frequent Advisor

building dynamically a find command

Hi,

 

To simplify I will to come with a short example.

Suppose

I want to run something like this:

    LOG_DIR="/su01/"

    LOG_NAME=*.log

    AA="-user toto -o -user tata"

    myFIND="find $LOGDIR -type f -name ${LOG_NAME}  \( $AA \) -print"

 

I don't want a substitution for the * joker and echo ${myFIND} should show this

find /su01 -type f -name *.log  \( -user toto -o -user tata \) -print

and not

find /su01 -type f -name afile_001.log \( -user toto -o -user tata \) -print

 

 

 

After that I will be able to execute the myFIND command

myfind

 

 

Any ideas ?

Kind regards, Den.

 

 

5 REPLIES 5
Steven Schweda
Honored Contributor

Re: building dynamically a find command

> LOG_NAME=*.log

   Normally (without quotation or escapes or disabling "globbing"), the
shell will expand that "*.tmp", which you apparently don't want.  One
way to avoid that is quotation:

      LOG_NAME='*.log'
or:
      LOG_NAME="*.log"

> After that I will be able to execute the myFIND command
>
> myfind

   Eh?  "myFIND" is a shell variable, not a command (or alias).  You
can't "execute" it that way.  (And "myfind" is not "myFIND".)

> [...] echo ${myFIND} should show this [...]

mba$ touch fred.log
mba$ LOG_DIR="/su01/"
mba$ LOG_NAME='*.log'
mba$ AA="-user toto -o -user tata"
mba$ myFIND="find $LOG_DIR -type f -name ${LOG_NAME}  \( $AA \) -print"

mba$ echo "$myFIND"
find /su01/ -type f -name *.log  \( -user toto -o -user tata \) -print

but:

mba$ echo $myFIND
find /su01/ -type f -name fred.log \( -user toto -o -user tata \) -print

   It can help to try to think about these expressions the way the shell
thinks about them (which can be complicated).

> To simplify [...]

   Too simple.  What, exactly, would you like to do?

SwissKnife
Frequent Advisor

Re: building dynamically a find command

Hi Steven,

Thanks to try to help here.

I need to build dynamically my find command and then execute it.

The bigest problem I have (and why I need to build it dynamically before to execute), is that I don't know users. This is why I need to parse users, build the string with -user n1 -o -user n2 ..... -o -user n.

You see.

 

Kind regards,

Den.

Steven Schweda
Honored Contributor

Re: building dynamically a find command

> You see.

   Not entirely.

   I'll guess that you could use a shell script.  This shell script
could be executed with a command like "myscript" (if it's on your PATH).
Somewhere in this shell script, you'd have a "find" command, and some of
the items on the "find" command line would be variables.

   Among the things I still don't know:

> LOG_DIR="/su01/"

   How do you want to specify this directory?  Or is it always the same?

> LOG_NAME=*.log

   How do you want to specify this (wildcard) file spec?  Or is it
always the same?

> AA="-user toto -o -user tata"

   How do you want to specify the list of users?  (You could specify the
actual "find" options, or the script could take a space-separated list
of users, and add the "-user" and "-o" tokens, for example.  As usual,
many things are possible.)

> [...]  What, exactly, would you like to do?

   "Exactly" includes all the details.

   If your worst problem is stopping the shell from expanding "*.log",
then adding some quotation marks may solve it.  If you want to write a
fancy shell script, then you need first to decide what you'd like it to
do.

   I can imagine a script which you might run like this:

      ./myfind /su01 '*.log' toto tata

I don't want to write it, but it should be possible.

Steven Schweda
Honored Contributor

Re: building dynamically a find command

   Some potentially useful techniques:

pro3$ cat f1.sh
#!/bin/sh

echo "arg1: >$1<"
echo "arg2: >$2<"

shift 2

args="$@"

echo "args: >${args}<"

fa=` echo ${args} | sed -e 's/  */ -o -user /g' `
fa=` echo ${fa} | sed -e 's/\([^ ].*\)/-user \1/' `

echo "fa: >${fa}<"


pro3$ ./f1.sh dir '*.log' u1 u2 u3
arg1: >dir<
arg2: >*.log<
args: >u1 u2 u3<
fa: >-user u1 -o -user u2 -o -user u3<

Dennis Handly
Acclaimed Contributor

Re: building dynamically a find command

>Normally (without quotation or escapes or disabling "globbing"), the shell will expand that "*.tmp"

 

I had a complicated case recently where I just gave up and used the noglob hammer.

I had multiple levels of quoting and expansion.

for command in \

   "showspace -cpg *" \

   ; do

   set -f # noglob

   cli $command

done

 

I couldn't quote the $command since I want it to expand into multiple tokens.

I tried using '*" but the app didn't like it.  I used \"*\" and it worked, only because the app ignored the quotes.

So it seem that noglob was the right solution in my case.

 

> build the string with -user n1 -o -user n2 ..... -o -user n.

 

Build that dynamically but the rest statically and Steven showed?