1

I have a .txt converted from .csv that looks like this

Smith","example","example","example","example"
example","Smith","example","example","example"
example","Smith","example","Smith","example"
example","example","example","Smith","example"
John","example","example","example","example"
example","example","example","John","example"

I want to only keep lines that contain the words Smith or John but they have to be within the first two fields

Output should be:

Smith","example","example","example","example"
example","Smith","example","example","example"
example","Smith","example","Smith","example"
John","example","example","example","example"

The first two fields might not exactly be John or Smith, they could be Johnson for example, I would still like to keep that.

If the first two fields don't contain either John or Smith then that line should be removed. If the first or second fields contain them the line should be kept no matter what (if the whole line had "John" for example)

  • No leading quote? That seems to me a somewhat ill-formed CSV, is it really correct? – yaegashi Jun 17 '15 at 12:41
  • Yes (12 chara limit) – Teddy291 Jun 17 '15 at 12:41
  • May the fields contain comas? – Stéphane Chazelas Jun 17 '15 at 12:57
3
grep -E '^([^,]*,")?(Smith|John)'  <infile

...will print...

Smith","example","example","example","example"
example","Smith","example","example","example"
example","Smith","example","Smith","example"
John","example","example","example","example"
  • grep -E '^([^,]+,")?(Smith|John)"' <newname.txt > new.txt - Created an empty file. I forgot to mention sorry that the line might not exactly be "Smith" it could be Smithy, just contain "Smith" – Teddy291 Jun 17 '15 at 12:44
  • @Teddy291 - Ok, so are you not trying definitely to match the whole field? I stuck that last quote in specifically to guard against Smithy - I never liked that guy. – mikeserv Jun 17 '15 at 12:45
  • Exactly, there could be "Smithy", "Johnson", "Smithy Sucks" - I would like to keep them all :) – Teddy291 Jun 17 '15 at 12:46
  • @Teddy291 - try it without the trailing quote then - it will only match the head of each field - anything may follow. And tell Smithy I want my $20. – mikeserv Jun 17 '15 at 12:47
2

Using awk:

< inputfile awk -F, '$1$2~/Smith|John/'

Output:

~/tmp$ cat inputfile
Smith","example","example","example","example"
example","Smith","example","example","example"
example","Smith","example","Smith","example"
example","example","example","Smith","example"
John","example","example","example","example"
example","example","example","John","example"
~/tmp$ < inputfile awk 'BEGIN {FS=","} $1~/Smith|John/||$2~/Smith|John/'
Smith","example","example","example","example"
example","Smith","example","example","example"
example","Smith","example","Smith","example"
John","example","example","example","example"
  • 2
    I would use awk -F, rather than awk 'BEGIN { FS=","} . – Archemar Jun 17 '15 at 12:57
  • 1
    If you use FS="\",\"" (or -F'","') it will also handle possible commas within the quoted fields, I think? – steeldriver Jun 17 '15 at 12:57
  • @steeldriver Yes, it does, thanks for the input – kos Jun 17 '15 at 13:04
  • @Archemar I'm not sure. I've always done it like that because i use gawk, so I think that's the most compatible way as long as I don't use very specific features, because there's no risk to break options. However it might be that -F is supported an almost all versions, I've never checked. If that's the case well, I'd fancy it more either. – kos Jun 17 '15 at 13:06
  • 2
    Yes, -F is POSIX.. You also don't need to escape the ", if you want to use FS, you could do BEGIN{FS=","}. Alternatively, in addition to -F,, you can also do awk -vFS=",". Finally, you could condense the whole thing to awk -F, '$1$2~/Smith|John/'. – terdon Jun 17 '15 at 13:50

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.