在 bash 脚本中使用 sed 或 grep 检查文件是否以特定字符串结尾

在 bash 脚本中使用 sed 或 grep 检查文件是否以特定字符串结尾

我的ubuntu服务器上有一个名为output.txt的文件,如何使用sed或grep检查文件中的最后两个字符是否为“nt”文件中的文本如下,我希望我的if语句返回true在这种情况下。

参议院通过了一项包含六项法案的一揽子计划,为联邦政府的部分部门提供资金直至 9 月,勉强避免了部分政府关门

上议院以 75 票对 22 票通过,该法案在午夜截止日期前送到了拜登总统的办公桌上

预计拜登先生将于周六签署该法案

共和党要求对与移民相关的措施和其他措施进行修正案投票,这导致了该法案的通过速度放缓,并在资金失效后威胁将最终投票推迟到周六。

“我们给国家带来了好消息,”参议院多数党领袖、纽约民主党人查克·舒默在投票前表示

“我们将继续为母亲和孩子、退伍军人、环境、住房等重要项目提供资助。由于双方今天的合作,我们朝着为政府提供全额资金的目标迈出了重要一步

答案1

我真的不会在这里使用sedor grep。你可以,但在我看来,tail更简单。用于tail获取文件的最后三个字节(我们需要三个字节来说明尾随字符)(请注意,如果您正在寻找一个更复杂的 Unicode 字符串,其中每个字符可以超过一个字节,则\n这将不起作用nt),然后检查是否匹配nt

if [ "$(tail -c3 file)" = "nt" ]; then 
  echo yes
else
  echo no
fi

您可以使用 GNU 来做到这一点grep,例如将整个文件(假设它不包含 NUL 字符)视为单个“行”并检查最后一个字符:

if grep -qPz 'nt\n$' file; then
 echo yes
else
 echo no
fi

或者,用sed,类似这样的东西(或者@steeldriver 更好更简单GNU 特定方法):

if [ "$(sed -n '${/nt$/p;}' file | wc -c)" -gt 0 ]; then 
  echo yes; 
else 
  echo no
fi

甚至perl

if perl -ne '$l=$_; }{ exit($l=~/nt$/ ? 0 : 1)' file; then 
 echo yes
else
 echo no
fi

答案2

由于 Ubuntu 有 GNU sed,其quit 命令具有返回状态代码的扩展,因此您可以寻址最后一行,如果它以状态 0 结尾nt或以非零结尾,则以状态 0 退出,例如。

 if sed -n '${/nt$/q0;q1}' output.txt; then ...

您可能需要将非零状态设置为大于 4 的值,以将其与 sed 的其他可能的状态区分开来退出状态

答案3

使用(以前称为 Perl_6)

Raku 是 Perl 家族的一种编程语言。 Raku 具有布尔值TrueFalse(枚举)值。通过 Bool例程或等效的强制so“是这样吗?”) 例程产生所需的True/False输出。


忽略尾随空白:

使用文件句柄(即$fh.eof):

~$ raku -e 'my $fh = $*ARGFILES.IO.open;  \
            .match(/ nt \h* $/).Bool.say if $fh.eof for $fh.lines;'  file

使用lines.tail

~$ raku -e '.match(/ nt \h* $/).Bool.say for lines.tail;'  file

#OR:

~$ raku -e 'lines.tail.match(/ nt  \h* $/).Bool.put;'  file

更简单lines.tail

~$ raku -e 'm/ nt \h* $/.so.put for lines.tail;'  file

删除或以其他方式处理尾随空白:

True如果最后一行以nt, 结尾,则顶部部分的答案可以很好地返回,False否则。但False如果文件仅包含一个或多个尾随换行符,则会返回顶部部分的答案。为了给出更准确的布尔答案,可以按如下方式处理尾随空格:

删除(单个)终端换行符和任何生成的尾随空格:

~$ raku -e '.match(/ nt $/).Bool.say for lines.tail(2).chomp.trim-trailing;'  file

删除所有尾随空白行(通过slurp):

~$ raku -e '.match(/ nt $/).Bool.say for slurp.trim-trailing;'  file

跳过尾随空白行(通过lineschars):

~$ raku -e 'my $fh = $*ARGFILES.IO.open;  \
             my $a = $_ if .chars for $fh.lines();  \
             $a.match(/ nt $/).Bool.say;'  file

#OR

~$ raku -e 'my $a = $_ if .chars for lines(); put $a ~~ m/ nt $/.so;'  file

https://docs.raku.org/type/Bool
https://docs.raku.org
https://raku.org

答案4

这是一个非常简单的示例,说明如何使用 grep 和 sed 来实现它:

#!/usr/bin/bash

result=$(grep -o 'nt$' 'Output.txt' | sed '$!d')
if [ "$result" = 'nt' ]; then
   echo 'Matched !'
else
   echo 'Not found !'
fi

解释:

  • -o 仅打印匹配的部分。
  • $ 匹配行的每个结尾
  • '$!d' 删除除最后一行之外的所有行。

相关内容