我正在搜索字符串::=BEGIN
,并且想应用一个条件来检查是否找到了该单词。
所以,我的意思大致如下:
if (sed command does find a match for "::=BEGIN")
then i=1
else i=0
另外,我希望将 1(表示找到)和 0(表示未找到)放入变量“i”中。
请帮帮我。也请解释一下解决方案!谢谢!
答案1
使用 GNUsed
(任何 Ubuntu 系统上都默认安装):
{ sed -n '/::=BEGIN/Q 1'; i=$?; } <infile
关于这个答案的一些事实:
sed
Q
uits 输入第一场比赛在文件中的任何位置都可以找到 - 这意味着它不会再浪费时间继续读取文件。sed
返回在其退出代码数值0或者1取决于它是否无法找到所寻址的正则表达式。$i
设置为sed
退出时的返回。分组用于稳健地处理任何可能的重定向错误 -在 shell 根本
{
无法打开文件的情况下不设置,从而避免误报。; }
$i
不过,这可能不应该被优先考虑grep -q
,因为基本上还完成以上所有操作(若反向),以 POSIX 方式执行,并且通常更快。
已经给出的grep -q
答案非常好,但是有点简洁:
grep -q pattern ./infile; i=$((!$?))
答案2
grep
这项工作做得足够好。
$ echo "::=BEGIN" > testfile1.txt
$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND"
FOUND
$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
FOUND
$ grep "whever" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
NOTFOUND
代码所做的只是在子 shell 中运行静默搜索。&&
或逻辑 AND 操作数检查第一个命令是否成功,如果成功,则运行echo "FOUND"
。||
检查该 echo 是否已运行,即,我们是否发现任何内容。 仅当第一个命令失败时,才会运行第二个 echo。
这是一个awk
版本:
$ awk '{i="NOTFOUND";if($0~/::=BEGIN/) i="FOUNDIT";exit } END { print i}' testfile1.txt
FOUNDIT
$ awk '{i="NOTFOUND";if($0~/whatevs/) i="FOUNDIT";exit } END { print i}' testfile1.txt
NOTFOUND
这里的基本思想是设置i
为NOTFOUND
,如果我们找到字符串 - 将其更改为FOUNDIT
。最后,在第一组完成文件处理后,我们将打印i
,它会告诉我们是否找到了什么。
编辑:在评论中,您提到要将结果放入变量中。 Shell 已经提供了一个变量来报告上一个命令的退出状态。$0
退出状态 0 表示成功,其他所有状态 - 失败。例如,
$ grep "::=BEGIN" -q testfile1.txt
$ echo $?
0
如果要在变量中使用退出状态,可以这样做:MYVAR=$(echo $?)
。请记住,$? 报告前一个命令的退出状态。因此,必须在 grep 命令之后立即使用它。
如果你仍想使用我之前的 awk 和 grep 单行命令,你可以使用相同的技巧MYVAR=$()
,将你想要的任何命令放在括号之间。输出将被分配给变量MYVAR
。
答案3
你可以使用这个:
#!/bin/bash
while IFS= read -r line; do
case "$line" in *::=BEGIN*) i=1 && break;;
*) i=0
esac
done <file.txt
这将file.txt
逐行搜索文件,如果::=BEGIN
找到匹配项,它将设置变量i=1
并退出。如果没有找到匹配项,则将变量设置为i=0
。
答案4
sed
(溪流编辑) 不是处理此类事情的正确工具:您可以简单地使用语句bash
if
将您的输入与正则表达式进行匹配:
#!/bin/bash
#...
input="$(< inputfile)"
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
#...
input="$(< inputfile)"
:将的内容inputfile
赋给变量$input
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
:将正则表达式::=BEGIN
与变量的内容进行匹配$input
;如果匹配则将其分配1
给$i
,否则将其分配0
给$i