John
John

Reputation: 593

UNIX Shell Script remove one column from the file

I have a file like the following:

Header1:value1|value2|value3|
Header2:value4|value5|value6|

The column number is unknown and I have a function which can return the column number.

And I want to write a script which can remove one column from the file. For exampple, after removing column 1, I will get:

Header1:value2|value3|
Header2:value5|value6|

I use cut to achieve this and so far I can give the values after removing one column but without the headers. For example

value2|value3|
value5|value6|

Could anyone tell me how can I add headers back? Or any command can do that directly? Thanks.

Upvotes: 0

Views: 6454

Answers (8)

AAAfarmclub
AAAfarmclub

Reputation: 2360

Just chiming in with a Perl solution:
(rearrange/remove fields as needed)

-l effectively adds a newline to every print statement
-a autosplit mode splits each line using the -F expression into array @F
-n adds a loop around the -e code
-e your 'one liner' follows this option

$ perl -F[:\|] -lane 'print "$F[0]:$F[1]|$F[2]|$F[3]"' input.txt

Upvotes: 0

user3172259
user3172259

Reputation: 1

$ cat file.txt | grep 'Header1' | awk -F"1" '{ print $1 $2 $3 $4}'

This will print all values in separate columns. You can print any number of columns.

Upvotes: 0

chepner
chepner

Reputation: 530970

Replace the colon with a pipe, do your cut command, then replace the first pipe with a colon again:

sed 's/:/|/' input.txt | cut ... | sed 's/|/:/'

You may need to adjust the column number for the cut command, to ensure you don't count the header.

Upvotes: 2

John
John

Reputation: 476

awk can handle multiple delimiters. So another alternative is...

jkern@ubuntu:~/scratch$ cat ./data188 
Header1:value1|value2|value3|
Header2:value4|value5|value6|
jkern@ubuntu:~/scratch$ awk -F"[:|]" '{ print $1 $3 $4 }' ./data188 
Header1value2value3
Header2value5value6

Upvotes: 1

Slava Semushin
Slava Semushin

Reputation: 15204

My solution:

$ sed 's,:,|,' data | awk -F'|' 'BEGIN{OFS="|"}{$2=""; print}' | sed 's,||,:,'
Header1:value2|value3|
Header2:value5|value6|
  • replace : with |
  • -F'|' tells awk to use | symbol as field separator
  • in each line we replace 2nd (because header now becomes first) field with empty string and printing result line with new field separator (|)
  • return back header by replacing first | with :

Not perfect, but should works.

Upvotes: 0

rush
rush

Reputation: 2564

you can do it just with sed without cut:

sed 's/:[^|]*|/:/' input.txt

Upvotes: 0

MutoKenji
MutoKenji

Reputation: 46

Your problem is that HeaderX are followed by ':' which is not the '|' delimiter you use in cut.

You could separate first your lines in two parts with :, with something like "cut -f 1 --delimiter=: YOURFILE", then remove the first column and then put back the headers.

Upvotes: 1

twalberg
twalberg

Reputation: 62369

Turn the ':' into '|', so that the header is another field, rather than part of the first field. You can do that either in whatever generates the data to begin with, or by passing the data through tr ':' '|' before cut. The rest of your fields will be offset by +1 then, but that should be easy enough to compensate for.

Upvotes: 1

Related Questions