Equivalent of grep to awk or sed
awk
is superset of grep
, so you can use that grep
pattern in awk
as well:
awk '{match($0, "[^ ]+$"); if (RSTART > 0) print substr($0, RSTART, RLENGTH)}'
in 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
In sed:
sed -nr 's/(|.* )([^ ]+)$/\2/p'
\thanks{cuonglm}
and (why not?) in Perl
perl -nlE '/([^ ]+)$/ and say $1'
Let's go over what your grep
command does first:
- the
-o
tellsgrep
to output only the matching part instead of the whole line - the
-E
flag allows use of extended regular expressions '[^ ]+$'
will match any non-space character repeated one or more times at the end of the line - basically a word at the end of the line.
Test run:
$ cat input.txt
to be or not to be
that is the question
$ grep -oE '[^ ]+$' input.txt
be
question
Now, how can we do the same in awk
? Well that's easy enough considering that awk
operates by default on space-separated entries of each line (we call them words - awk
calls them fields). Thus we could print $NF
with awk - take the NF
variable for number of fields and treat it as referring to specific one. But notice that the grep
command would only match non-blank lines, i.e. there is at least one word there. Thus, we need to a condition for awk
- operate only on lines which have NF
number of fields above zero.
awk 'NF{print $NF}' input.txt
It should be noted that GNU awk at least supports extended regex (I'm not familiar with others as extensively, so won't make claims about others). Thus we could also write a variation on cuonglm's answer:
$ awk '{if(match($0,/[^ ]+$/)) print $NF}' input.txt
be
question
With GNU sed
one can use extended regular expressions as well - that requires -r
flag, but you can't simply use same regular expression. There's a need to use backreference with \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
It is possible to obtain desired result with basic regular expression like so:
$ cat input.txt
to be or not to be
that is the question
blah
$ sed 's/^.* \([^ ].*\)$/\1/' input.txt
be
question
blah
For more info, please refer to these posts:
can we print the last word of each line in linux using sed command?
https://unix.stackexchange.com/a/31479/85039