我正在尝试使用Shell Scripting逐行读取文本文件。我一直在做的是
while read line
do
var1=$(grep -s "Completed" $line)
var2=$(grep -s "Script Finished" $line)
if[ "$var1" = "$line" ]
break
else
if[ "$var2" = "$line" ]
count='expr $count + 1'
else
countinue
fi
fi
done < file.txt
如果您有任何建议,请告诉我们!我对其他选择持开放态度,因为我一直试图这么做。
要澄清:
我逐行浏览一个文件(while循环)然后我在grepping那一行,看看“Completed”是否是一个子字符串,并且看看“Script Finished”是否是一个子字符串(Grep会将变量设置为整条线)。那么当我检查变量是否已完成时我想要打破while循环,如果不检查“Script Finished”是否为子串,那么我可以增加一个计数器(我试图计算在完成之前完成的脚本数量)完成“)。
疑惑:
当我执行var1 = $(grep -s“已完成”$ line)为什么它会找到所有已完成的实例...我想如果我逐行浏览它只会找到该行中的实例。
编辑:
我使用了下面的awk答案。我所要做的就是删除{next}语句,它完美无缺。
谢谢
答案 0 :(得分:4)
您有几个错误。另外,您可能需要考虑一种用于执行此类操作的工具。 awk就是其中一种工具。
awk '/blah blah/ {exit}
/Finished/ {count+=1}
{next}
END{ print count} ' filename
当第一行在线上的任何地方匹配“blah blah”时退出。
第二行计算“完成”匹配的数量。
{next}位用于继续读取而不是每行打印 - 这在某些版本的awk中会发生。
最后一行END {}函数在代码完成文件时运行。它显示count的值。
我选择了awk方法而不是尝试修复shell脚本中的逻辑和语法错误。如果您需要这种帮助,请考虑在命令行上单独播放几乎所有代码块(或行)。我假设你使用了bash。
错误示例
-eq to compare strings, use =, example: [ "$var" = "something" ]
$(var1) should be either "${var1}" or "$var1" lines 4 and 8
grep返回整行,你是否正在测试“等等”并期待只是因为整个结果只是“等等”?
答案 1 :(得分:2)
错误#1:
当我做var1 = $(grep -s“已完成”$ line)时为什么会找到所有 已完成的实例
在上面的命令中grep
期望$line
是文件名而不是字符串。如果要传递字符串,则需要使用管道:
var1=$(echo "$line" | grep -s "Completed")
或者在Bash中你可以使用字符串重定向:
var1=$(grep -s "Completed" <<<"$line")
错误#2:
if
和[
之间应该有空格([
是test
命令)
<小时/> 此
grep
命令可能与您尝试使用该代码时的操作相同:
grep -v "Completed" file.txt | grep -c "Script Finished"
grep -v "Completed" file.txt
返回不包含“Completed”的行,并通过管道发送到下一个grep
,该管道返回包含文本“Script Finished”的行计数。
答案 2 :(得分:1)
我在(当前)接受的解决方案之后发布此消息,因为接受的解决方案是使用标记未涵盖的语言。
你可以使用case语句在shell中做同样的事情。 (虽然对于大文件,awk或grep可能更快)
while read line; do
case "$line" in
*"Completed"*)break;;
*"Script Finished"*)count=$((count + 1));;
esac
done < file.txt
注意:这种形式的while read line;
...将省略最后一行,如果不行,请使用while read line || [ "$line" ]
(这是为什么某些IDE会向空行添加空行的原因之一文件结尾)