Print out specific field using regular expression in Linux
It would be more direct, in my opinion, to use a tool like awk
that can:
- split fields for you
- test exactly the fields you want for the values you want
For example:
awk -F: '$4 == 1001 || $4 == 1003' mypasswd
... tells awk to:
- split the incoming lines into fields based on colons, with
-F:
- uses an "or" expression to test whether field 4 has the value 1001 or 1003
- if the condition above is true, then print the line (the default action)
Awk can take a little bit to learn; one of the major things to understand about it is that it uses paired "pattern" and "action" statements. The "pattern" section(s) determine which "action" statements get executed.
You could rewrite the above awk to make it more explicit; by doing so, we can explicitly print whatever we want (such as the 5th field):
awk -F: '$4 == 1001 || $4 == 1003 { print $5 }'
... or to have an empty "pattern" section -- meaning, execute the "action" for every line, and then test inside the action pattern for the values:
awk -F: '{ if ($4 == 1001 || $4 == 1003) print $5 }'
To force grep
into action, you could do:
grep -E '^([^:]*:){3}(1001|1003):' mypasswd | cut -d: -f5
To tell it to look, from the beginning of the line, for the group "anything-that-isn't-a-colon any number of times, followed a colon" three times, followed by either 1001 or 1003, then followed by a colon; print the whole matching line, but then pass it to cut
to print just the 5th field.
I might do this with sed
sed -n '/^.*:.*:.*:\(1001\|1003\):/p' mypasswd
The -n
supresses the lines and the p
at the end prints the ones that match.
you could also do it with grep
grep '^.*:.*:.*:1002\|1003:.*:.*:' mypasswd
As @JeffSchaller says, awk
is the tool for the job and since OP wants regex
we can just combine the two
awk -F: '$4 ~ /^100[13]$/' mypasswd
and that allows a little golf putt on the grep
version
grep -E "^(.*:){3}100[13]:" mypasswd