我有一个包含一些文件的目录。我想知道每个文件中是否存在某个单词。
$1
是我作为参数提供的目录
例如./myscript.sh /mnt/c/User/er/Desktop/shows
我已经编写了这段代码,但终端显示此错误:[: it21754 :binary operator expected
#!/bin/bash
for a in $( find "$1" -type f )
do
if[ egrep 'it21754' $a ]
then
echo "0"
else
echo "1"
fi
done
答案1
不要循环 的输出find
。这是相当不优雅的,因为完整的find
命令必须完成并产生全部它在循环甚至可以运行其第一次迭代之前的输出。此外,您的脚本无法正确处理包含空格的文件名。命令替换的结果将按空格分割以生成用于循环的单词。
相反,让find
命令为循环生成文件名,如下所示:
find "$1" -type f -exec sh -c '...loop here...' sh {} +
我们很快就会回到这个话题。
语法就行
if[ egrep 'it21754' $a ]
有点奇怪,你绝对不需要egrep
这里(grep
就足够了)。
我所说的“奇怪”是指[ ... ]
测试通常看起来像[ op arg ]
or [ arg op arg ]
where op
is some 像-f
or or 一样的运算符,-eq
并且=
是arg
一个字符串。您使用egrep
andit21754
以及任何$a
扩展为的内容,这就是生成您得到的错误的原因。你实际上无法egrep
在这种情况下跑步,也不需要这样做。
正确的if
说法是
if grep -qwF 'it21754' "$a"; then
echo 0
else
echo 1
fi
标志-qwF
使grep
安静(-q
),它使用字符串比较而不是正则表达式( )进行匹配-F
,并且它确保匹配的字符串将是一个完整的单词而不是子字符串(-w
)。这里我们使用退出状态来grep
选择是输出0(匹配)还是1(不匹配)。
我还用双引号引起$a
来,以防"$a"
文件名包含任何空格或文件名通配符。
有趣的是,这些数字grep
无论如何都用于其退出状态,因此我们可以将整个过程缩短为
grep -qwF 'it21754' "$a"
echo "$?"
该$?
变量保存最近执行的命令的退出状态。
将其插入我们的find
命令中,我们得到
find "$1" -type f -exec sh -c '
for a do
grep -qwF "it21754" "$a"
echo "$?"
done' sh {} +
这将产生许多 1 和 0,具体取决于文件是否包含给定的单词。但是,我认为您可能正在寻找包含该单词而不是零或一的文件的文件名。为此我们可以使用
find "$1" -type f -exec grep -lwF 'it21754' {} +
在这里,我将 更改-q
为 a -l
(“dash ell”)。这会调用grep
找到的文件grep
并将仅有的输出包含给定单词的文件名。我们不再需要这个sh -c
位了,因为我们调用的是单个实用程序(不是grep
和 echo
)。
当然,你可以做同样的事情只是 grep
:
grep -R -lwF 'it21754' "$1"
使用-R
,grep
将递归搜索命令行上给出的子目录。
可能值得注意的是-w
和-R
标志grep
不是标准的,而是由最常见的grep
变体实现的。
有关的: