问题
Can this be done in Awk?
FILE_IN (Input file)
ID_Number|Title|Name
65765765|The Cat Sat on the Mat|Dennis Smith
65765799|The Dog Sat on the Catshelf|David Jones
65765797|The Horse Sat on the Sofa|Jeff Jones
FILE_OUT (Desired Results)
ID_Number|Title|Nickname|Name
65765765|The Cat Sat on the Mat|Cat Sat|Dennis Smith
65765799|The Dog Sat on the Catshelf|Dog|David Jones
65765797|The Horse Sat on the Sofa||Jeff Jones
Logic to apply:
IF Title contains “ Cat Sat ” OR " cat sat " THEN Nickname = “Cat Sat” #same titlecase/text as was found#
IF Title contains “ Dog ” OR " dog " THEN Nickname = “Dog”
Also, is this task possible with Sed?
回答1:
another awk
$ awk 'BEGIN{FS=OFS="|"}
{delete a;
match($2,"([Cc]at [Ss]at|[Dd]og)",a);
$NF=(NR==1?"Nickname":a[1]) OFS $NF}1' file
ID_Number|Title|Nickname|Name
65765765|The Cat Sat on the Mat|Cat Sat|Dennis Smith
65765799|The Dog Sat on the Catshelf|Dog|David Jones
65765797|The Horse Sat on the Sofa||Jeff Jones
回答2:
This might work for you (GNU sed):
sed -i '1s/|/&Nickname&/2;1b;s/|.*\b\(Cat\|Dog\)\b.*|/&\u\1|/I;t;s/|.*|/&|/' file
Insert the column Nickname
into the headings. If the second column contains either the word Cat
or Dog
insert a third column with the matching word in it. Otherwise insert a blank third column.
回答3:
You could try this with GNU awk
:
awk -F"|" -v OFS="|" 'NR==1{$2 = $2 OFS "Nickname"}
NR>1{if($0 ~ /\s*[Cc]at [Ss]at\s+/) n="Cat"; else if($0 ~ /\s*[dD]og\s+/)n="Dog";
else n=""; $2 = $2 OFS n} 1' file
-F "|" OFS="|"
to specify delimiter input and output respectively.NR==1
To handle header case.NR>1
To handle data case.
With the same logic, you could use this more compacted code:
awk -F"|" -v OFS="|" 'NR==1{$2 = $2 OFS "Nickname"}
NR>1{n=($0 ~ /\s*[Cc]at [Ss]at\s+/) ? "Cat" : ($0 ~ /\s*[dD]og\s+/) ? "Dog" : ""; $2 = $2 OFS n} 1' file
来源:https://stackoverflow.com/questions/51730561/how-to-use-awk-to-create-a-new-field-but-retain-the-original-field