Given an input like this


I want to delete every second and fourth word in each line using sed. Words are strictly alphanumeric.

  • "Every 2nd word" would include the 4th word. Do you mean "the 2nd and 4th word on each line"?
    – Kusalananda
    Commented Apr 19, 2020 at 9:12
  • Sorry, I did not specify more precisely. I meant exactly the 2nd and 4th word on each line.
    – Paralyz3d
    Commented Apr 19, 2020 at 9:15
  • Do you want to remove only the 2nd/4th word even though a field may contain multiple words? Or does a field only ever contain a single word?
    – Kusalananda
    Commented Apr 19, 2020 at 9:42
  • 1
    Should the separating commas be removed, too? Please add a sample output.
    – FelixJN
    Commented Apr 19, 2020 at 11:33
  • Please show us your expected output. "Every second word" means you want to delete the 2nd, 4th, 6th, 8th etc. "Every fourth" would mean deleting the 4th, 8th, 12th, 16th etc. Without an example output it's very hard to understand what you mean.
    – terdon
    Commented Apr 19, 2020 at 13:12

5 Answers 5


The most natural tool for this is cut.

cut -d , -f 1,3,5-

With sed, use \([^,]*,\) to match one field.

sed 's/^\([^,]*,\)\([^,]*,\)\([^,]*,\)\([^,]*,\)/\1\3/'
  • Or sed 's/^\([^,]*,\)[^,]*,\([^,]*,\)[^,]*,/\1\2/'. Note that the sed ones assume all lines have at least 5 fields. sed 's/,[^,]*//3; s/,[^,]*//' would take care of those. Commented Apr 19, 2020 at 12:19
  • What if you want the second and the 113th ? Should you write a very long request?
    – Sandburg
    Commented Oct 6, 2020 at 13:28

it's not sed, but you can use Miller (https://github.com/johnkerl/miller) and run

<input mlr --csv -N unsparsify then cut -x -f 2,4

to have


If you just want to remove the 2nd and 4th fields on each line, you can do:

$ perl -F, -lane 'print join ",", @F[0,2,4..$#F]' file

The -n tells perl to read an input file and apply the script given by -e to each line. The -a causes perl to act like awk and split its input on the character given by -F and save the result in the array @F. Then, join ",",@F[0,2,4..$#F]' makes a new string by joining the 1st and 3rd fields (arrays start from 0) and then the 5th field and everything else until the end of the array ($#F is the highest index in the array), and the print print this string.

awk '{ split($0,a,","); delete a[4]; delete a[2]; for (i=1;i<=length(a); i++){ if(a[i]!="") printf "%s,", a[i] }; printf "\n";}' inputfile

This second one does not work, despite this line in man gawk:

Assigning a value to an existing field causes the whole record to be rebuilt when $0 is referenced. Similarly, assigning a value to $0 causes the record to be resplit, creating new values for the fields.

gawk 'BEGIN{ FS=","; OFS="," }{ $2=""; $4=""; a=$0; $0=a; print $0 }' inputfile

EDIT: Above does not work because of the FS and gow awk handles them, and that's why this works:

gawk 'BEGIN{ FS=","; OFS="," }{ gsub(FS $2,""); gsub(FS $4,""); print $0 }'


  • @Cyrus, but this, indeed shorter, version will output this,,a,,string,, so two commas after this, which is same as my last version.
    – Luuk
    Commented Apr 19, 2020 at 12:18
  • added an edit with working second version...
    – Luuk
    Commented Apr 20, 2020 at 6:01
awk 'BEGIN{FS=",";OFS=","}{$2=$4="\b";print $0}' file
  • This works for this case, where inner fields are deleted, including the delimiters. But in general, the backspace character is moving the cursor back, when the output is rendered, not actually deleting content. Here, when $2 is rendered, the cursor goes one position back, and the next comma overwrites the previous one. But if you had to remove the last column and use $NF="\b", the last comma would remain, because there are no more characters to overwrite it. Or for other cases, it could have unexpected behaviour.
    – thanasisp
    Commented Apr 18, 2022 at 10:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .