排除文件的grep数组参数

时间:2017-01-02 15:17:42

标签: linux bash grep

我想从grep命令中排除一些文件,为此我使用参数:

--exclude=excluded_file.ext

为了更容易阅读,我想使用带有排除文件的bash数组:

EXCLUDED_FILES=("excluded_file.ext")

然后将$ {EXCLUDED_FILES}数组传递给grep,如:

grep -Rni "my text" --exclude=${EXCLUDED_FILES}

如何将数组作为参数传递给grep命令?

5 个答案:

答案 0 :(得分:9)

变量不作为参数传递给程序; 是。变量(尤其是数组)由shell扩展为一个或多个单词,每个单词作为单独的参数传递给程序。在这种特定情况下,--exclude选项将单个文件名作为其参数,因此您需要从数组中构建多个--exclude=foo参数。一种选择:

for f in "${EXCLUDED_FILES[@]}"; do
    opts+=( --exclude="$f" )
done
grep -Rni "my text" "${opts[@]}"

答案 1 :(得分:6)

我想你正在寻找这个:

grep -Rni "${excluded_files[@]/#/--exclude=}" "my text"

参数展开"${excluded_files[@]/#/--exclude=}"将扩展为数组excluded_files的扩展,每个字段都以--exclude=为前缀。看:

$ excluded_files=( '*.txt' '*.stuff' )
$ printf '%s\n' "${excluded_files[@]/#/--exclude=}"
--exclude=*.txt
--exclude=*.stuff

答案 2 :(得分:2)

GNU grep还支持--exclude-from选项,该选项将 filename 作为其参数,引用的文件包含要排除的模式,每个模式都在其自己的行上。

如果您不担心带有嵌入换行符的文件名(很少有人担心),您可以使用以下流程替换来动态创建这样的文件:

grep -Rni "my text" --exclude-from=<(printf '%s\n' "${EXCLUDED_FILES[@]}")

顺便说一下:最好不要使用全大写的shell变量名来avoid conflicts with environment variables and special shell variables

答案 3 :(得分:2)

当他们为grep文件提供find选项时,GNU的人真的搞砸了。接下来的内容 - sort输出的选项或tr安全字符或仅打印结果的head / tail?用于查找文件的UNIX工具具有非常简单明了的名称find。 UNIX工具grep也恰当地命名为&#34; G 与一个文件中的 R egular E xpression进行全局匹配 P 判断结果&#34;。

所以find找到文件,而grep从匹配正则表达式的文件中打印字符串 - 2个非常不同的目的,你应该像UNIX设计师那样为每个作业使用正确的工具:

findsarg=()
for f in "${EXCLUDED_FILES[@]}"
do
    findsarg+=( '!' -name "$f" )
done
find . -type f "${findsarg[@]}" -exec grep -Hni "my text" {} +

感谢@gniourf_gniourf帮助获取处理包含globbing元字符和空格的文件名的语法。

正如其他地方所述 - 不按惯例使用非导出变量的所有大写名称,以避免与导出/标准名称发生冲突。

答案 4 :(得分:1)

您不能将数组作为参数传递给任何命令。所有参数都是字符串。

但是,您可以将数组转换为包含所有数组元素的字符串,并以分隔符(默认情况下为一个空格字符)分隔。语法是

grep -Rni "my text" --exclude="${EXCLUDED_FILES[*]}"

但是,我应该指出,GNU --exclude的{​​{1}}参数不起作用。它的值被视为单个 glob,用于过滤结果。这不同于grep参数将文件的每一行视为单独的glob的行为。如果要在命令行中指定多个排除球,那么您需要为每个参数分别提供--exclude-from参数。