4

I have a find command that finds files with name matching multiple patterns mentioned against the -name parameter

find -L . \( -name "SystemOut*.log" -o -name "*.out" -o -name "*.log" -o -name "javacore*.*" \)

This finds required files successfully at the command line. What I am looking for is to use this command in a shell script and join this with a tar command to create a tar of all log files. So, in a script I do the following:

LIST="-name \"SystemOut*.log\" -o -name \"*.out\" -o -name \"*.log\" -o -name \"javacore*.*\" "
find -L . \( ${LIST} \)

This does not print files that I am looking for.

First - why this script is not functioning like the command? Once it does, can I club it with cpio or similar to create a tar in one shot?

5 Answers 5

7

Looks like find fails to match * in patterns from unquoted variables. This syntax works for me (using bash arrays):

LIST=( -name \*.tar.gz )
find . "${LIST[@]}"

Your example would become the following:

LIST=( -name SystemOut\*.log -o -name \*.out -o -name \*.log -o -name javacore\*.\* )
find -L . \( "${LIST[@]}" \)
Sign up to request clarification or add additional context in comments.

Comments

1
eval "find -L . \( ${LIST} \)"

3 Comments

evil is as evil does
Comming late to this SO thread. Have a look at my answer !
1

You could use an eval and xargs,

eval "find -L . \( $LIST \) " | xargs tar cf 1.tar

Comments

1

When you have a long list of file names you use, you may want to try the following syntax instead:

# List of file patterns
Pat=( "SystemOut*.log"
"*.out"
"*.log"
"javacore*.*" )

# Loop through each file pattern and build a 'find' string
find $startdir \( -name $(printf -- $'\'%s\'' "${Pat[0]}") $(printf -- $'-o -name \'%s\' ' "${Pat[@]:1}") \)

That method constructs the argument sequentially using elements from a list, which tends to work better (at least in my recent experiences).

You can use find's -exec option to pass the results to an archiving program:

find -L . \( .. \) -exec tar -Af archive.tar {} \;

4 Comments

+1 for the construct, this does not get results from with in a script, though.
@ringbearer- Can you explain what you mean by "does not get results from within a script"? I use that particular code snippet in several different scripts.
Following error:"find: paths must precede expression" - Using the following: GNU find version 4.2.27 Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX and here is the find construct printed via echo : find /opt/appserver \( -name *.out -o -name "*.log core*.*" -o -name "javacore*.*" -o -name "heapdump*.*" -name "server.log_*" \)
Oops, it looks like I quoted the wildcard expressions incorrectly (I should have used single-quotes instead of double-quotes). See my updated answer for a correctly-quoted version.
0
LIST="-name SystemOut*.log -o -name *.out -o -name *.log -o -name javacore*.*"

The wildcards are already quoted and you don't need to quote them again. Moreover, here

LIST="-name \"SystemOut*.log\""

the inner quotes are preserved and find will get them as a part of the argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.