参数扩展在“find -exec”中不起作用

问题描述:

我正在编写一个bash脚本,但参数扩展与EXC变量不起作用。在EXC可变参数扩展在“find -exec”中不起作用

#!/bin/bash 
EXC="--exclude='*.js' --exclude='*.sh'" 
find /path -exec grep ${EXC} "xxx" {} \; >> result.txt 

的选项不使用grep电话,因为它仍然解析JavaScript文件...

也试过

find /path -exec grep $EXC "xxx" {} \; >> result.txt 
+0

这与[击FAQ 50](http://mywiki.wooledge.org/BashFAQ/050)。 – chepner

什么的问题是,单引号不会从参数扩展删除,因此grep正在接收'*.js'作为模式,而不是*.js如你所愿。您需要使用一个数组来保存的参数:

exc=("--exclude=*.js" "--exclude=*.sh") # No single quotes needed 
find /path -exec grep "${exc[@]}" "xxx" {} \; >> result.txt 

的报价参数扩展防止*.js*.sh从字面上不使用时引述他们以同样的方式被shell扩展。 --exclude='*.js''--exclude=*.js'都会导致相同的参数被传递到grep,最低限度--exclude=\*.js也是如此。你也可以定义数组作为

exc=(--exclude "*.js" --exclude "*.sh") 

由于长选项及其参数可以被指定为包含=或作为两个单独的词一个词。

+0

这不是单引号问题。我试着用双引号逃脱,它也没有工作。阵列做到了这一点,但对我而言,外壳扩展的工作原理仍然不清楚。虽然用'$ {var}'扩展了一个简单的'var = string'是无效的,用'“{$ var [@]}”扩展的'var =(strings ...)'工作。我期望将相同的逻辑应用于变量和数组,但显然不是。 –

+1

这是不同的,因为数组的引入恰恰是为了解决你使用常规变量所遇到的问题。当从字面上输入'grep --exclude ='*。js''时,shell会删除单引号,因为它们只用于告诉shell'* .js'不应该展开。 'grep'接收字符串'--exclude = *。js'作为参数。但是,当将该字符串存储在变量中时,单引号没有特殊含义。字符串'--exclude ='*。js''被视为几乎肯定无法匹配的模式,因此会与引号一起直接传递给'grep' *。 – chepner

+0

现在我明白了......但是为什么'var =“ - exclude = *。js”'仍然不能和'cmd'一起使用$ {var}“'?这里没有单引号,所以shell不应该担心,因为我的变量只是一个随便的字符串。 –

您可以过滤find结果与!(不)运营商结合-name选项。为了排除.js.sh文件:

find . -type f ! -name '*.js' ! -name '*.sh' -exec grep xxx {} \; 
+0

我的问题是不排除一些文件,我可以写出整个命令行。问题是我使用一个变量来保存一些参数,并且参数扩展不能通过它在命令行中的值来代替$ {}事物。我尝试了您的解决方案,符合我的要求,但仍然无法正常工作,因为grep一直在解析.js文件 –

它仍然解析,或者它只是还找到您所要排除的文件应用?

无论如何,为什么不使用只的grep -r而不是找到grep的

grep -r --exclude='*.js' --exclude='*.sh' "xxx" /path 
+0

使用变量和参数扩展在筛选或grep风格中筛选无效。我没有使用递归grep,因为它解析了二进制文件,这与我的情况不相关。 –

+0

同样,我的问题是不过滤文件。问题是我需要参数化我的命令行(在某些使用情况下)有很多不同的文件扩展名排除 –

的问题是,我使用一个变量来保存一些参数和参数扩展不通过其在命令行中值替换$ {}东西......

可以启动一个子shell至极将执行您想要

#!/bin/bash 
EXC="--exclude='*.js' --exclude='*.sh'" 
find /path -exec bash -c "grep ${EXC} 'xxx' {}" \; >> result.txt 

这些可以帮助你;

#!/bin/bash 
EXC="--exclude='*.js' --exclude='*.sh'" 
find /path -exec echo "grep ${EXC} 'xxx' {}" \; | bash > result.txt 

#!/bin/bash 
EXC="*js,*sh" 
find /path -exec echo "grep --exclude={${EXC}} 'xxx' {}" \; | bash > result.txt