Linux 被排除文件的grep数组参数

Linux 被排除文件的grep数组参数,linux,bash,grep,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命令?变量不会作为参数传递给程序;价值观是。shel

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

--exclude=excluded_file.ext
为了更易于阅读,我希望使用包含排除文件的bash数组:

EXCLUDED_FILES=("excluded_file.ext")
然后将${EXCLUDED_FILES}数组传递给
grep
,如下所示:

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

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

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

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

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

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

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

然而,我应该指出,GNU
grep
--exclude
参数不是这样工作的。其值被视为一个用于过滤结果的单个全局变量。这与
--exclude from
参数将文件的每一行视为单独的glob的行为不同。如果要在命令行上指定多个排除全局变量,则需要为每个全局变量分别提供一个
--exclude
参数。

GNU
grep
还支持
--exclude from
选项,该选项以文件名为参数,引用的文件包含要排除的模式,各自为政

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

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

grep-Rni“我的文本”--exclude from=我想你在找这个:

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

GNU的家伙们给了
grep
查找
ing文件的选项,结果真的搞砸了。下一步是什么-选择
排序
它的输出或
tr
转换字符或只打印结果的
/
?用于查找文件的UNIX工具有一个非常贴切和明显的名称
find
。UNIX工具
grep
也被恰当地命名为“G全局匹配文件中的RegularExpression并打印结果”

因此,
find
查找文件,而
grep
从与regexp-2非常不同的用途相匹配的文件中打印字符串,并且您应该按照UNIX设计者的意图为每个作业使用正确的工具:

findsarg=()
for f in "${EXCLUDED_FILES[@]}"
do
    findsarg+=( '!' -name "$f" )
done
find . -type f "${findsarg[@]}" -exec grep -Hni "my text" {} +
感谢@gniourf_gniourf提供的帮助,使语法正确,可以处理包含全局元字符和空格的文件名


不过,正如其他地方所提到的-根据惯例,非导出变量不要使用所有大写名称,以避免与导出/标准名称冲突。

要么使用glob expression,要么在grep上做一个补丁。我尝试使用
排除
并动态创建一个文件,但未成功:
grep--exclude from=“$(@fedorqui)您正试图以命令的形式执行进程替换的文件名。请删除
$(…)
。做得很好;因为您不经常看到它,所以很容易忘记这样的参数扩展也适用于数组。做得很好。请解释${excluded_files[@]/\35;/--exclude=}的含义是什么/#/“有点像foreach吗?@daniftodi:expansion
${array[@]/pattern/replacement}”
“${array[@]}的扩展“
第一次出现的
模式
替换
替换的地方是数组
数组
的每个字段。模式中的
符号是字符串开头的锚定符。同样,
%
是字符串结尾的锚定符。@gniourf\gniourf谢谢。”。