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?

ring bearer
  • 20,383
  • 7
  • 59
  • 72

6 Answers6

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[@]}" \)
lunixbochs
  • 21,757
  • 2
  • 39
  • 47
1
eval "find -L . \( ${LIST} \)"
h0tw1r3
  • 6,618
  • 1
  • 28
  • 34
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 {} \;
bta
  • 43,959
  • 6
  • 69
  • 99
  • +1 for the construct, this does not get results from with in a script, though. – ring bearer Apr 27 '12 at 14:21
  • @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. – bta Apr 27 '12 at 17:47
  • 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_*" \) ` – ring bearer Apr 28 '12 at 17:19
  • 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. – bta May 01 '12 at 19:27
1

You could use an eval and xargs,

eval "find -L . \( $LIST \) " | xargs tar cf 1.tar
dpp
  • 1,748
  • 11
  • 7
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.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

Building -name list for find command

Here is a proper way to do this:

cmd=();for p in \*.{log,tmp,bak} .debug-\*;do [ "$cmd" ] && cmd+=(-o);cmd+=(-name "$p");done

Or

cmd=()
for p in \*.{log,tmp,bak,'Spaced FileName'} {.debug,.log}-\* ;do
    [ "$cmd" ] && cmd+=(-o)
    cmd+=(-name "$p")
done

You could dump you $cmd array:

declare -p cmd
declare -a cmd=([0]="-name" [1]="*.log" [2]="-o" [3]="-name" [4]="*.tmp" [5]="-o"
     [6]="-name" [7]="*.bak" [8]="-o" [9]="-name" [10]="*.Spaced FileName" 
     [11]="-o" [12]="-name" [13]=".debug-*" [14]="-o" [15]="-name" [16]=".log-*")

Then now you could

find [-L] [/path] \( "${cmd[@]}" \)

As

find \( "${cmd[@]}" \)

(Nota: if no path is submited, current path . is default)

find /home/user/SomeDir \( "${cmd[@]}" \)

find -L /path -type f \( "${cmd[@]}" \)
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137