Delete a column from a delimited file in linux

2020-02-12 04:55发布

问题:

I have a file in the following format:

col1|col2|col3|col4
a|b|c|d
e|f||h
i|j|k|l

I would like to delete col3 (with the delimiter "|") from the header and the data as well. Can this be done using awk/sed?

Plese NOTE that the data in col3 maybe empty (row 2).

The output should be:

col1|col2|col4
a|b|d
e|f|h
i|j|l

回答1:

You could simply use cut.

cut -d'|' -f1-2,4- file


回答2:

This might work for you (GNU sed):

sed 's/[^|]*|//3' file


回答3:

awk  'BEGIN{FS=OFS="|"}{print $1,$2,$4}'   file

should give you the output.

it is the very basic awk usage.

edit

you didn't mention 70 columns... :(

try this:

awk  -F'|' '{s="";for(i=1;i<=NF;i++){f=(NF==i)?"":FS;if(i!=3)s=s $i f;}print s}' file


回答4:

Here's a possible sed solution:

sed -i.bak filename -e 's;\(^.*|.*|\).*|\(.*\);\1\2;'

This will work great for your example, and could be adjusted for other examples, but isn't really a general purpose solution.

Explanation:

-i.bak Edit the file in place, first making a backup called filename.bak.

\(^.*|.*|\) From the start of the line, match everything up to and including the second delimiter. The parenthesis group this match (group 1).

.*| Match everything up to and including the last delimiter.

\(.*\) Match the rest and group (group 2).

\1\2 Replace all of the previous matches with the text from group 1 and group 2.



回答5:

Using cut is the right answer, but if you really want to use awk it's easier than Kent shows:

awk -F'|' 'BEGIN {OFS="|"} {for (n=3; n < NF; ++n) $n = $(n+1); --NF; print}'

Just shuffle the fields after $3 down, then by altering the value of NF you change the number of fields.



回答6:

cut command will help to achieve this

 cat filname | cut -d'|' -f1,2,4


回答7:

Another awk solution could be useful if you have many columns

awk -F'|'  '{$3="";$0=$0;$3=$3}1' FPAT='[^|]+' OFS='|' file


标签: linux unix awk sed