使用shell变量查找具有多个文件名的-name

时间:2012-04-26 21:31:21

标签: bash shell find

我有一个find命令,用于查找名称与-name参数

提到的多个模式匹配的文件
find -L . \( -name "SystemOut*.log" -o -name "*.out" -o -name "*.log" -o -name "javacore*.*" \)

在命令行中成功找到所需文件。我正在寻找的是在shell脚本中使用此命令并使用tar命令将其连接以创建所有日志文件的tar。因此,在脚本中我执行以下操作:

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

这不会打印我要查找的文件。

首先 - 为什么这个脚本不像命令一样运行?一旦完成,我可以使用cpio或类似的方式与其联系以一次创建tar吗?

6 个答案:

答案 0 :(得分:6)

看起来find无法与未加引号变量的模式中的*匹配。这个语法适用于我(使用bash数组):

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

您的示例将成为以下内容:

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

如果您使用了很长的文件名列表,则可能需要尝试以下语法:

# 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}") \)

该方法使用列表中的元素按顺序构造参数,这样可以更好地工作(至少在我最近的经验中)。

您可以使用find的-exec选项将结果传递给归档程序:

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

答案 3 :(得分:1)

您可以使用eval和xargs,

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

答案 4 :(得分:0)

LIST="-name SystemOut*.log -o -name *.out -o -name *.log -o -name javacore*.*"

已经引用了通配符,您无需再次引用它们。而且,这里

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

内部引号被保留,find将它们作为参数的一部分。

答案 5 :(得分:0)

-name 命令构建 find 列表

这是一个正确的方法:

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

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

您可以转储 $cmd 数组:

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-*")

那么现在你可以

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

作为

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

(注意:如果没有提交路径,默认为当前路径.

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

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