I currently use the following to delete all emails that contain EXAMPLE

sed -i '/EXAMPLE/d' newname.csv

However that deletes lines that have EXAMPLE in any of the columns. I want it to only delete lines that contain EXAMPLE in the second column. Columns are separated with tabs. (example below)

pa**s-***c.com  support@n**.com George Ka*****os    Athens  Athens  1****   GREECE

Due to tab problems none of the below that I have tried work, so alternatively I will cover to .txt and columns look like this

"pak**o.asia","jav***vip@live.com","T**iq Ja**id","Rajan Pur","punjab","33***0","PAKISTAN"

marked as duplicate by Anthon, Michael Homer, G-Man, Gilles, mdpc Jun 17 '15 at 23:35

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Do you want to keep lines where the 2md field is fooEXAMPLEbar or does EXAMPLE need to be the entire field? – terdon Jun 17 '15 at 15:01
  • Wait - it says delete the line? So... which should we do, do you think? – mikeserv Jun 17 '15 at 15:02
  • Sorry I was confused, if the second column has EXAMPLE anywhere in it, for example fooEXAMPLEbar that line should be removed. – Teddy291 Jun 17 '15 at 15:04
grep -v '^[^\t]*\t[^\t]*EXAMPLE' <newname.csv >outfile

But you might need to use literal <tab> characters there depending on which grep you use.

The same goes for sed below. Be warned that using -i comes with certain filesystem security implications:

sed -i '/^[^\t]*\t[^\t]*EXAMPLE/d' ./file

Or maybe a little more tricky:

sed -i 'h;s/\t/\n/2;/\t.*EXAMPLE.*\n/d;g' ./file

For your example data w/ the commas:

sed -i '/^[^,]*,[^,]*EXAMPLE/d' ./file

Gets the whole line deleted when EXAMPLE is found before another comma after the first occuring comma.

  • How can I run this to delete without printing on screen? I will be running multiple commands one this file, EXAMPLE wont be the only word to remove. – Teddy291 Jun 17 '15 at 15:09
  • The following doesn't work (to delete any emails with the word example in them) sed -i '/^[^\t]*\t[^\t]*example/d' ./newname.csv – Teddy291 Jun 17 '15 at 15:22
  • I can't get it working. I have updated my first post with what it looks like after I convert to .txt - How would I do it with that format? – Teddy291 Jun 17 '15 at 16:03
  • That didn't work and no email has commas - How could I do it with the "," separator (after I convert to .txt, see first post) – Teddy291 Jun 17 '15 at 16:14
  • @Teddy291 - I just did another - you wanna try it? It's at the bottom. Weird about the tabs. – mikeserv Jun 17 '15 at 16:16

Perl can do this quite handily:

use strict;
use warnings;

while (<>) {
    print unless ( split )[1] =~ m/EXAMPLE/;

That's an unanchored regex - you might want m/^EXAMPLE$/ instead.

This can one-liner-ify as:

perl -ne 'print unless ( split )[1] =~ m/^EXAMPLE$/';

Such task is actually simpler and easier to understand using awk, only that awk has no in-place file edit:

$ awk '$2 !~ /EXAMPLE/ {print $ALL}' old.csv > new.csv

  • 1
    What is {print $ALL} supposed to do? – jasonwryan Jun 17 '15 at 19:50
  • $ALL means the whole line. But note that the variable works for Linux but might not for some other OS. In that case one would use {print;} instead. – Abel Cheung Jun 18 '15 at 2:43
  • $0 is the entire record in Awk. And it is printed by default. Your answer is incorrect on two counts. – jasonwryan Jun 18 '15 at 3:49
  • @jasonwryan Would you care about mentioning how it is incorrect? Other than $ALL shall not be used in nawk, I have tested on Linux and Freebsd with 3 different implementations: mawk, gawk, nawk, and still fail to see how and where it was incorrect. – Abel Cheung Jun 18 '15 at 6:12
  • More correct '$2 !~ /EXAMPLE/ {print $0}'; idiomatic: '$2 !~ /EXAMPLE/'... – jasonwryan Jun 18 '15 at 8:17

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