How to extract values from a text file for a multiline pattern which has three fields "ID", "First name" and "Last name"?
Extract only the pattern where the "ID" field has 9 digits with two spaces in there and the "First name" field not equal to "XXXXX". Remove the two spaces in the "ID" field. Remove the "Gender" field in the "First name" line.
e.g. Input:
ID : 200 000 000
Address: Test
First name: XXXXX Gender: M
Last name: YYYYY
ID : 123 456 789
Address: Anywhere 1
First name: Albert Gender: M
Last name: Au
ID : YYY YYY YYY
ID : ZZZ ZZZ ZZZ
ID : 100 000 000
Address: Anywhere 2
First name: Priscilla Gender: F
Last name: Chan
ID : QQQ ZZZ ZZZ
Address: Test 2
First name: XXXXX Gender: M
Last name: ZZZZZ
Output:
ID : 123456789
First name: Albert
Last name: Au
ID : 100000000
First name: Priscilla
Last name: Chan
I modified αғsнιη's original command below to:
awk -v RS='' -F'\n|: *' '{ bkup=$0 } gsub("Address:", "", bkup) && gsub("Gender:", "", bkup) && gsub($4, "", bkup) && gsub(" ", "", $2)==2 && $2+0==$2 && $6 !~ /^XXXXX *Gender$/ { print bkup }' infile.txt
Output:
ID : 123 456 789
First name: Albert M
Last name: Au
ID : 100 000 000
First name: Priscilla F
Last name: Chan
I modified αғsнιη's improved command below to:
awk -v RS='' -F'\n|: *' '{ bkup=$0; id=$2; gsub(/\nAddress[^\n]*\n| *Gender *: *[MF]\n/, "\n", bkup) } gsub(" ", "", $2)==2 && $2+0==$2 && gsub(id, $2, bkup) && $6 !~ /^XXXXX *Gender$/ { print bkup }' infile.txt
Output as expected:
ID : 123456789
First name: Albert
Last name: Au
ID : 100000000
First name: Priscilla
Last name: Chan
How to get the expected output with sed?
If the input have more spaces and extra characters in the ID field, how to get the expected output? e.g.
Input:
ID : 200 000 000 Status : 1
Address: Test
First name: XXXXX Gender: M
Last name: YYYYY
ID : 123 456 789 Status : 2
Address: Anywhere 1
First name: Albert Gender: M
Last name: Au
ID : YYY YYY YYY Status : _
ID : ZZZ ZZZ ZZZ Status : _
ID : 100 000 000 Status : 3 XYZ
Address: Anywhere 2
First name: Priscilla Gender: F
Last name: Chan
ID : QQQ ZZZ ZZZ Status : 4
Address: Test 2
First name: XXXXX Gender: M
Last name: ZZZZZ
I modified nezabudka's solution below to:
sed -nr '/ID : ([0-9]{3} ){2}[0-9]{3}/!b s/\s//3g :1;N;/Last name/!b1 /First name: XXXXX/!s/(Gender|Status|\nAddress)[^\n]*//gp ' infile2.txt
Output:
ID :123456789
First name: Albert
Last name: Au
ID :100000000
First name: Priscilla
Last name: Chan
Expected output - the ID field is modified to the same format as the First name field:
ID: 123456789
First name: Albert
Last name: Au
ID: 100000000
First name: Priscilla
Last name: Chan