I need to print only the 1st match from each line.
My file contains text something like this:
cat t.txt
abcsuahrcb
abscuharcb
bsaucharcb
absuhcrcab
He is the command I am trying with:
cat t.txt | grep -oP 'a.*?c'
It gives:
abc
ahrc
absc
arc
auc
arc
absuhc
I need it to return:
abc
absc
auc
absuhc
These are the 1st possible matches from each line.
Any other alternatives like sed and aws will work, but not something which needs to be installed on Ubuntu.
CodePudding user response:
Perl to the rescue:
perl -lne 'print $1 if /(a.*?c)/' t.txt
-nreads the input line by line, running the code for each;-lremoves newlines from input lines and adds them to output;- The code tries to match
a.*?c, if matched, it stores the result in $1; - As there's no loop, only one match per line is attempted.
CodePudding user response:
A sed variation on The fourth bird's answer:
$ sed -En 's/^[^a]*(a[^c]*c).*/\1/p' t.txt
abc
absc
auc
absuhc
Where:
-En- enable extended regex support, suppress automatic printing of pattern space^[^a]*- from start of line match all follow-on characters that are nota(a[^c]*c)- (1st capture group) match letteraplus all follow-on characters that are notcfollowed by ac.*- match rest of line\1/p- print contents of 1st capture group
One awk idea:
$ awk 'match($0,/a[^c]*c/) { print substr($0,RSTART,RLENGTH)}' t.txt
abc
absc
auc
absuhc
Where:
- if we find a match then the
match()call is non-zero (ie, 'true') so ... - print the
substring defined by theRSTART/RLENGTHvariables (which are auto-populated by a successfulmatch()call)
CodePudding user response:
Using grep you could write the pattern as matching from the first a to the first c using a negated character class.
Using -P for Perl-compatible regular expressions, you can make use of \K to forget what is matched so far.
Note that you don't have to use cat but you can add the filename at the end.
grep -oP '^[^a]*\Ka[^c]*c' t.txt
The pattern matches:
^Start of string[^a]*Optionally match any char excepta\KForget what is matched so faraMatch literally[^c]*Optionally match any char exceptccMatch literally
Output
abc
absc
auc
absuhc
Another option with gnu-awk and the same pattern, only now using and printing the capture group 1 value:
awk 'match($0,/^[^a]*(a[^c]*c)/, a) { print a[1]}' t.txt
