I have a csv file, and I want to delete lines if their 12th character is not ;.

So, for example, my file looks like this:


and I want:


How can I remove a line if the 12th character in it is NOT ; with sed? =)

  • You are asking two different questions here. Do you want to delete lines whose Nth character is not ; or lines whose Nth field is >1 in length?
    – terdon
    Mar 17, 2016 at 13:21
  • delete lines whose Nth character is not ; - this one)
    – Konstantin
    Mar 17, 2016 at 13:22
  • Are you sure? If you're working with field-based data, it makes more sense to deal with fields instead of characters. What if one of the lines starts with a space? What if one fo the lines has a longer 1st field than you expect?
    – terdon
    Mar 17, 2016 at 13:23
  • Yes, I'm pretty sure, but thanks for option =) My file is well aligned and that would be the best case for solution in my opinion =)
    – Konstantin
    Mar 17, 2016 at 13:24
  • But it is an option actually, depends on which way is easier to declare in sed =)
    – Konstantin
    Mar 17, 2016 at 13:27

1 Answer 1


To delete all lines whose 12th character is not ;, you could do:

 $ sed -E '/^.{11}[^;]/d' file

Or, to edit the original file (if your sed supports -i):

$ sed -iE '/^.{11}[^;]/d' file

And if your sed doesn't support -E:

sed -i '/^.\{11\}[^;]/d' file

However, since this is a csv file, it is much safer to use fields instead of character counts. For example, use awk and tell it to print all lines whose 3rd field is one character long:

$ awk -F';' 'length($3)==1' file

With recent GNU awk, you can edit the file in place:

 awk -iinplace -F';' 'length($3)==1' file

This has the advantage of being robust to changes in the lengths of the preceding fields. Unlike the sed approach, it won't fail if you have leading whitespace on a line or if any of the 1st 2 fields are longer (or shorter) than you expect. As a general rule, if your data is field-separated, using the fields is a better idea than using character positions.

  • You have forgot the -i option, to edit the file in place: sed -i -E '/^.{11}[^;]/d' file
    – Eliad
    Mar 17, 2016 at 14:16
  • sed -i ain't portable to e.g. OpenBSD.
    – thrig
    Mar 17, 2016 at 14:51
  • @thrig true but most implementations (including FreeBSD, ) do. But OK, I added a disclaimer.
    – terdon
    Mar 17, 2016 at 14:57
  • can't seem to restrain impulse to upvote every time I see awk -iinplace
    – iruvar
    Mar 17, 2016 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.