我有以下find,sed和grep命令。
find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) -prune -o -type f \( -name "*.bat" \) -exec grep -L 'FOO' {} \; -print0 | xargs -0 sed -i -e '1iFOO'
我希望能够在目录中找到所有不包含字符串“ FOO”的.bat
文件,并将它们通过管道传输到sed命令,该命令将字符串“ FOO”添加到文件顶部。但是,当我运行命令的find和grep部分(不使用sed)时:
find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) -prune -o -type f \( -name "*.bat" \) -exec grep -L 'FOO' {} \; -print
它返回所有bat文件,甚至包含字符串'FOO'的文件。这使我相信grep命令是错误的。我怎样才能解决这个问题?谢谢
答案 0 :(得分:0)
-exec
的{{1}}参数指定一个测试:如果返回0,则包括结果;否则返回0。如果返回非零,则排除结果。 find
不管是否找到结果都返回0,因此它等效于grep -L
(或完全不传递-exec true \;
)。
您可以通过将-exec
命令的输出通过find
:grep
传递到xargs
来获得所需的结果。
答案 1 :(得分:0)
更改:
grep -L 'FOO'
收件人:
awk '/FOO/{exit 1}'
因此,只有文件中不存在FOO时,才打印文件名。
为清楚起见,整个命令行将是:
find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) \
-prune -o -type f \( -name "*.bat" \) \
-exec awk '/FOO/{exit 1}' {} \; -print0 |
xargs -0 sed -i -e '1iFOO'
答案 2 :(得分:0)
grep
打印出不匹配的文件名(使用换行符而不是null作为终止符)。您需要禁止输出grep
。也许:
find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) \
-prune -o -type f \( -name "*.bat" \) \
-exec sh -c '! grep -q "FOO" $1' _ {} \; -print0
但是写起来似乎更干净了
find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) \
-prune -o -type f \( -name "*.bat" \) \
-not -exec grep -q "FOO" {} \; -print0