Linux 在shell中进行比较时出错
我试图搜索一个模式(拖车),如果它在一个文件中出现多次,我需要显示这些文件名Linux 在shell中进行比较时出错,linux,shell,grep,Linux,Shell,Grep,我试图搜索一个模式(拖车),如果它在一个文件中出现多次,我需要显示这些文件名 for f in *.txt do if((tail -n 1 $f | grep '[9][9][9]*' | wc -l) -ge 2); then echo " The file $f has more than one trailer" fi done 最严重的语法错误是-ge是[…]或[…]]条件构造的运算符。它没有机会像你写程序那样-g
for f in *.txt
do
if((tail -n 1 $f | grep '[9][9][9]*' | wc -l) -ge 2);
then
echo " The file $f has more than one trailer"
fi
done
最严重的语法错误是
-ge
是[…]
或[…]]
条件构造的运算符。它没有机会像你写程序那样-ge
两边都需要一个数字,左边是一个命令。您可能希望获得命令的输出,这将需要命令替换语法:$(…)
。那是
if [ $(tail -n 1 $f | grep '[9][9][9]*' | wc -l) -ge 2 ]; then
这在语法上是正确的,但永远不会匹配tail-n1$f
只输出一行(除非文件为空),因此grep
最多只能看到一行,因此wc-l
打印0或1
如果要在多行上搜索模式,请更改tail
调用。当您使用时,您可以将grep…| wc-l
更改为grep-c
;两者的作用完全相同,即计算匹配的行数。例如,要搜索最后42行,请执行以下操作:
if [ $(tail -n 42 -- "$f" | grep -c '[9][9][9]*') -ge 2 ]; then
如果要在最后一行中搜索两个匹配项,则不同grep
没有帮助,因为它确定每行是否匹配,而不是每行查找多个匹配项。如果要在最后一行中查找多个不重叠的匹配项,请重复该模式,允许在中间插入任意文本。您正在测试模式是否存在,因此您只需要测试grep
的返回状态,而不需要它的输出(因此有-q
选项)
我更改了
tail
调用,以便在文件名以-
开头时添加-
(否则,tail
会将其解释为一个选项),并在文件名周围加双引号(如果它包含空格或\[*?
)。这些都是好习惯。始终在变量替换前后加上双引号。“$foo”和命令替换“$(foo)”
,除非您知道替换将导致以空格分隔的全局模式列表。尾部-n 1$f
将产生(最多)一行输出,输入到grep
,然后根据定义最多可以产生一行输出,这意味着wc
的输出永远不会超过1,特别是永远不会超过2。除了其他注释/答案中提到的语法问题外,我认为这个逻辑可能是c语言的一个原因除了你应该添加更多信息之外,为什么你还要有<代码>(尾部-N 1美元F GRIP)[9 ] [ 9 ] [9 ] *“WC-L”< /代码>,它应该是“代码> $(尾部…< /代码>),这是不必要的。请考虑(GRIP)[9 ] [9 ] [9 ] 'WC-L -GE 2);YVE:CHEC.SH:行23:在意外令牌>代码>附近的语法错误-GE'CHECK。SH:行23:< /代码>(tail-n1$f | grep'[9][9]*'| wc-l)-ge2);@Karoly-Horvath:hi-Karoly谢谢你的链接沃尔伯格:你是对的。问题在于语法和逻辑。最后我完成了。n1=
grep'[9][9]*'$f | wc l`if[$n1 ge2];然后,`这是完美的工作。谢谢你的反馈。我终于完成了脚本。
if tail -n 1 -- "$f" | grep -q '[9][9][9]*.*[9][9][9]*'; then