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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10341719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:08:08  来源:igfitidea点击:

find -name with multiple filenames using shell variable

bashshellfind

提问by ring bearer

I have a findcommand that finds files with name matching multiple patterns mentioned against the -nameparameter

我有一个find命令可以查找名称与-name参数中提到的多个模式匹配的文件

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 tarcommand to create a tar of all log files. So, in a script I do the following:

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

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 cpioor similar to create a tarin one shot?

首先 - 为什么这个脚本不像命令那样运行?一旦它出现,我可以用它cpio或类似的方法tar进行一次击球吗?

回答by lunixbochs

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

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

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[@]}" \)

回答by h0tw1r3

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

回答by bta

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 -execoption to pass the results to an archiving program:

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

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

回答by dpp

You could use an eval and xargs,

你可以使用 eval 和 xargs,

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

回答by n. 'pronouns' m.

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 findwill get them as a part of the argument.

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