You already got very good answers, which are easily the true go-to solutions for one-liners, but just in case you'd like or need to do it pure-bash only you might start from the following:
{ while read letters _ && [ "${letters}" != four ] ; do :; done ; read && read _ number _ && echo ${number} ; } < data.txt
It only yields the first occurrence of "four".
Here I used _
as the name for a placeholder variable, i.e. a variable that receives values to be discarded, and as an "added bonus" you have the | cut -f2
result already built into the script.
Also please note that above script is just a proof-of-concept: it only works with the exampled input data.
It could be enhanced by:
- reading the entire (unsplit) line to match it against a regex via the
[[
command (in place of [
) along with its =~
operator, like in: while read line && ! [[ "${line}" =~ four ]]
but beware the then additional complexity given by bash’s own escaping rules if the regex gets more complex than a simple "four"; also note the !
preceding the [[
to negate the test
- joining the
[
(or [[
) command with the two read
and the && echo ...
together inside the while loop, to not stop after first match, like in:
{ while read letters _ ; do [ "${letters}" = four ] && read && read _ number _ && echo ${number} ; done ; } < data.txt
Note also the change of the comparison operator. However beware of missing possibly adjacent matching lines. In order to address this possibility you’d need some kind of look-ahead or back-caching, for which you’d need some more advanced bash constructs.
Lastly, of course you can rather output the entire unsplit line via read line && echo ${line}
in place of read _ number _ && echo ${number}
four
will be unique)