48
votes

I have a file with three columns. I would like to delete the 3rd column(in-place editing). How can I do this with awk or sed?

123   abc  22.3
453   abg  56.7
1236  hjg  2.3

Desired output

123  abc
453  abg
1236 hjg 
7
I am puzzled: I opened a bounty to promote Ed Morton's answer and so far, the post with the most upvotes in these days has been the question, which did not show any research whatsoever (@_@).fedorqui 'SO stop harming'

7 Answers

25
votes

This might work for you (GNU sed):

sed -i -r 's/\S+//3' file

If you want to delete the white space before the 3rd field:

sed -i -r 's/(\s+)?\S+//3' file
66
votes

try this short thing:

awk '!($3="")' file
39
votes

With GNU awk for inplace editing, \s/\S, and gensub() to delete

1) the FIRST field:

awk -i inplace '{sub(/^\S+\s*/,"")}1' file

or

awk -i inplace '{$0=gensub(/^\S+\s*/,"",1)}1' file

2) the LAST field:

awk -i inplace '{sub(/\s*\S+$/,"")}1' file

or

awk -i inplace '{$0=gensub(/\s*\S+$/,"",1)}1' file

3) the Nth field where N=3:

awk -i inplace '{$0=gensub(/\s*\S+/,"",3)}1' file

Without GNU awk you need a match()+substr() combo or multiple sub()s + vars to remove a middle field. See also Print all but the first three columns.

16
votes

It seems you could simply go with

awk '{print $1 " " $2}' file

This prints the two first fields of each line in your input file, separated with a space.

8
votes

Try this :

awk '$3="";1' file.txt > new_file && mv new_file file.txt

or

awk '{$3="";print}' file.txt > new_file && mv new_file file.txt
8
votes

Try using cut... its fast and easy

First you have repeated spaces, you can squeeze those down to a single space between columns if thats what you want with tr -s ' '

If each column already has just one delimiter between it, you can use cut -d ' ' -f-2 to print fields (columns) <= 2.

for example if your data is in a file input.txt you can do one of the following:

cat input.txt | tr -s ' ' | cut -d ' ' -f-2

Or if you better reason about this problem by removing the 3rd column you can write the following

cat input.txt | tr -s ' ' | cut -d ' ' --complement -f3

cut is pretty powerful, you can also extract ranges of bytes, or characters, in addition to columns

excerpt from the man page on the syntax of how to specify the list range

Each LIST is made up of one range, or many ranges separated by commas.
Selected input is written in the same order that it is read, and is
written exactly once. Each range is one of:

  N     N'th byte, character or field, counted from 1
  N-    from N'th byte, character or field, to end of line
  N-M   from N'th to M'th (included) byte, character or field
  -M    from first to M'th (included) byte, character or field

so you also could have said you want specific columns 1 and 2 with...

cat input.txt | tr -s ' ' | cut -d ' ' -f1,2
0
votes

If you're open to a Perl solution...

perl -ane 'print "$F[0] $F[1]\n"' file

These command-line options are used:

  • -n loop around every line of the input file, do not automatically print every line

  • -a autosplit mode – split input lines into the @F array. Defaults to splitting on whitespace

  • -e execute the following perl code