grep 相当于 awk 或 sed

grep 相当于 awk 或 sed

我想知道相当于

grep -oE '[^ ]+$' pathname

awk 或 sed。如果有人可以回答并解释那就太好了。谢谢。

答案1

awk是 的超集grep,因此您也可以在以下位置使用该grep模式awk

awk '{match($0, "[^ ]+$"); if (RSTART > 0) print substr($0, RSTART, RLENGTH)}'

答案2

让我们grep首先回顾一下您的命令的作用:

  • 告诉只-o输出grep匹配的部分而不是整行
  • -E标志允许使用扩展正则表达式
  • '[^ ]+$'将匹配在行末尾重复一次或多次的任何非空格字符 - 基本上是行末尾的一个单词。

测试运行:

$ cat input.txt
to be or not to be
that is the question
$ grep -oE '[^ ]+$' input.txt                                      
be
question

现在,我们怎样才能在 中做同样的事情awk呢?考虑到awk默认情况下对每行以空格分隔的条目(我们称之为单词 -awk称之为字段)进行操作,这很容易。因此,我们可以$NF使用 awk 进行打印 - 获取NF字段数量的变量并将其视为引用特定字段。但请注意,该grep命令只会匹配非空行,即那里至少有一个单词。因此,我们需要一个条件awk- 仅对NF字段数大于零的行进行操作。

awk 'NF{print $NF}' input.txt

应该指出的是,GNU awk 至少支持扩展的正则表达式(我对其他人不太熟悉,所以不会对其他人提出要求)。因此,我们还可以根据 cuonglm 的答案写出一个变体:

$ awk '{if(match($0,/[^ ]+$/)) print $NF}' input.txt               
be
question

使用 GNUsed也可以使用扩展的正则表达式 - 这需要-r标志,但不能简单地使用相同的正则表达式。需要使用反向引用\1

$ cat input.txt                                                                                                          
to be or not to be
that is the question
blah 

$ sed -r -e 's/^.* ([^ ]+)$/\1/' input.txt                                                                             
be
question
blah

使用基本正则表达式可以获得所需的结果,如下所示:

$ cat input.txt                                                    
to be or not to be
that is the question
blah 
$ sed 's/^.* \([^ ].*\)$/\1/' input.txt                           
be
question
blah 

欲了解更多信息,请参阅这些帖子:

答案3

在 awk 中:

awk 'NF>0 {print $NF}'     ## fails with end of line spaces; \thnaks{cuonglm}
awk '/[^ ]$/ {print $NF}'  ## fails with tabs in lasts field; \thanks{Terdon}
awk -F ' +'  '$NF {print $NF}'            ## too tricky  
awk 'match($0,/[^ ]+$/,a){print a[0]}'    ## follows def. of grep -o

在 sed 中:

sed -nr 's/(|.* )([^ ]+)$/\2/p'

\谢谢{cuonglm}

以及(为什么不呢?)在 Perl 中

perl -nlE '/([^ ]+)$/ and say $1'

答案4

这与您尝试使用 grep 执行的操作等效于 sed:

# there is a space n a tab in the [...]
sed -ne '/[^  ]$/s/.*[    ]//p'

# this makes the code intent visually unambiguous
TAB=`echo 'x' | tr 'x' '\011'`; # tab
SPC=`echo 'x' | tr 'x' '\040'`; # space
h="[$SPC$TAB]";                 # whitespace
S="[^$TAB$SPC]";                # nonwhitespace

sed -ne "/$S\$/s/.*$h//p"

sed -ne "s/.*$h\($S$S*\)\$/\1/p"

相关内容