How to find out which separator occurred first using awk in bash?

How to find out which delimiter occurred first using a single line awk.

Suppose I have a file with the contents:

AB BC DE
BC DE AB
DE BC AB

And I want to know which of the three DE, AB, BCoccurred first in each line.

I thought I could use a separator BC, then take its first field, and then BC, and then take the first field AB.

It can be done:

$ awk -F'AB' '{print $1}' <file>   \
  | awk -F'BC' '{print $1}' <file> \
  | awk -F'DE' '{print $1}' <file>

However, is there any other way that I can dynamically change the delimiter inside the awk string and get the above thing using awk only once?

Edit: Fixed bugs made earlier.

+4
source share
3

, AB, BC DE newline, :

awk '{print $1}' file

. , , . , - , , ! , , , .

awk.

"" , . , , . , " :

RT ( gawk) , , RS, . , .

- :

$ echo "AB BC DE BC DE AB DE BC AB" \
   | awk 'BEGIN{RS="DE|AB|BC"}{print RT;exit }' 
AB

. RS . , awk.

$ awk 'BEGIN{RSSET="DE|AB|BC";RS=RSSET}
       (RS=="\n"){RS=RSSET;next}
       {print RT; RS="\n"; next}' file

AB BC DE BC DE AB DE BC AB
BC DE AB DE BC AB
DE AB DE BC AB

AB
BC
DE
+4

, :

awk 'match($0,/AB|BC|DE/){print substr($0,RSTART,RLENGTH)}' file

, , .

+6

A sed, . sed , , .

#!/usr/bin/sed -rnf

# This presumes you only want to print matching rows.
/(AB|CD|EF)/ {
    # add a line number
    =;
    # find first match, then remove rest of line
    s/(AB|CD|EF).*$/\1/;
    # this only leaves one possible match, so the greedy match all 
    # at the start doesnt match what we want.
    s/^.*(AB|CD|EF)/\1/; 
    # so print.
    p 
}

, "", , :

~$> printf "%b\n" "$letters"
ABa BBa ABb BBb ABc BBc
BBc ABc BBb ABb BBa ABa
ABb ABc BBa BBc
not right

~$> echo "$letters" | sed -rn '/(AB.|BB.)/ {=; s/(AB.|BB.).*$/\1/; s/^.*(AB.|BB.)/ \1/; p }'
1
 ABa
2
 BBc
3
 ABb
+1

Source: https://habr.com/ru/post/1692832/


All Articles