dsb
dsb

Reputation: 121

How to delete fields containing certain string or char?

I have a .txt file that contains

Name: Dean AGE: 23 Hometown: Chicago
Name: Mary AGE: 68 hometown: New York
Name: Lisa age: 36 Hometown: Los angeles
Name: Greg Age: 18 hometown: London

How would I sed, awk, or tr "Name:", "Age:" and "Hometown:" so the result is:

Dean 23 Chicago
Mary 68 New York
Lisa 36 Los angeles
Greg 18 London

The only things I can think of is to awk through all the fields and print them out such as:

awk '{for (i=1;i<=NF;i++) {if ($i !~/:/) {print i,$i}}}'

However this gives me the result:

Dean 
23 
Chicago
Mary 
68 
New 
York
Lisa 
36 
Los 
angeles
Greg 
18 
London

As you can see, it prints out every field on its own line and breaks up New and York, as well as Los and angeles.

The other idea I had was to sed "Name:", "Age:" and "Hometown:" one by one, all with different commands that replace them with nothing, which would work. Ex:

sed 's/Name://g'

However, is there a way to make it non-case sensitive, as there is "age:", "Age:", and "AGE:"

Upvotes: 1

Views: 373

Answers (5)

jas
jas

Reputation: 10865

What about deleting all the words ending in : from the input and printing what's left?

$ awk '{ gsub(/[^ ]+: /, "") }1' data.txt
Dean 23 Chicago
Mary 68 New York
Lisa 36 Los angeles
Greg 18 London

Edit: And as suggested in the comments, perhaps even more to the point is the sed equivalent:

sed -r 's/[^ ]+: //g' data.txt   # gnu

sed -E 's/[^ ]+: //g' data.txt   # bsd

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 247042

Piling on the answer, with perl:

To remove the specific labels:

perl -pe 's/(?:name|age|hometown): *//ig' file

To remove any label:

perl -pe 's/\w+:\s*//ig' file

tr is not the right tool, because it maps characters, not words.

Upvotes: 1

anubhava
anubhava

Reputation: 785691

You can use this gnu-awk command also:

awk -v IGNORECASE=1 -v OFS='\t' -F ' *(Name|AGE|Hometown): *' ' {
      printf $2; for (i=3; i<=NF; i++) printf OFS $i; print ""}' file
Dean    23    Chicago
Mary    68    New York
Lisa    36    Los angeles
Greg    18    London

Upvotes: 2

Ed Morton
Ed Morton

Reputation: 204229

$ awk -F' ?[^ ]+: ' '{print $2, $3, $4}' file
Dean 23 Chicago
Mary 68 New York
Lisa 36 Los angeles
Greg 18 London

or in general for any number of fields:

$ awk -F' ?[^ ]+: ' '{for (i=2;i<=NF;i++) printf "%s%s", $i, (i<NF?OFS:ORS)}' file
Dean 23 Chicago
Mary 68 New York
Lisa 36 Los angeles
Greg 18 London

Upvotes: 4

P.P
P.P

Reputation: 121407

If you have GNU sed, it has an option I for case-insensitive match:

sed 's/Name://gI;s/Age://gI;s/Hometown://gI' file

With a slight change, the awk solution would work:

awk '{ for(i=1;i<=NF;i++) {if ($i ~/:/) {$i=""}} ; print }' file

Upvotes: 4

Related Questions