我有一个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
吗?
答案 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[@]}" \)