I want to extract out those lines that contain g__something not followed by s__something in the lines. How can I do that?

Here's my text

  • No @karel. Actually that post is also mine. But I put that wrong. I have replied there. And soon going to remove that. – DEEP Aug 1 at 9:46
  • what happens with 'grep "g__" inputfile | grep -v "s__" > outputfile' ? It is a simple and basic way of doing it, I suppose that there are other possibile solutions, faster and more optimised than this one – Lorenz Keel Aug 1 at 9:48
  • thanks @Lorenz Keel. It works. What if I want to keep the first two lines as well? – DEEP Aug 1 at 11:01
  • Try this: 'head -2 inputfile > outputfile; grep "g__" inputfile | grep -v "s__" >> outputfile' Pay attention to >>, is not a mistake: it has the purpose to append the new line without overwriting. – Lorenz Keel Aug 1 at 11:22
  • 1
    @DEEP please add all your requirements in the body of your question. Please also post a textual example of your input and desired output. Please don't post images of text – steeldriver Aug 1 at 12:40

This awk command will unconditionally print the first two lines of file and print other lines that contain g__ except where it is followed by s__

awk 'NR<3 || /g__/ && !/g__.*s__/' file

Note that this solution will print lines where s__ precedes g__. If you want to exclude lines containing s__ regardless of whether it comes before or after g__, change the second condition to !/s__/

| improve this answer | |

This can be easily done in python3. The following program will print lines containing "g__" but not containing "s__".

Paste this in a file called find_g.py and put the data in data.txt

import sys

# Open the file for reading
with open(sys.argv[1]) as f:

    # Print first two lines without any condition
    print(f.readline(), end='')
    print(f.readline(), end='')

    # Check for condition in rest of the file
    for line in f:
        if "g__" in line and "s__" not in line:
            print(line, end='')


python3 find_g.py data.txt
| improve this answer | |
  • A suggestion: Either use this or the one given by @steeldriver. If you have a huge data set, grep solutions can occupy big amount of memory. – turbulence Aug 1 at 14:10
  • 1
    I agree with @turbulence, as I stated in my answer as well. I don't know python and my knowledge of awk is limited, these two solutions are more elegant and effective than mine ^_^' – Lorenz Keel Aug 1 at 14:35
  • @Lorenz Keel Even I am not much of the awk syntax. But AFAIK, awk matches the given expression line-by-line, thus does not need to load the entire file into memory. – turbulence Aug 1 at 16:44

Your requirements are: extract the first two lines and then the lines that contain the pattern "g__" but not "s__"

One simple way is the following:

head -2 inputfile > outputfile; grep "g__" inputfile | grep -v "s__" >> outputfile

The part before ';' extract the first two lines of inputfile and put them in outputfile. The part after ';' at first extract all lines containing "g__" and then, among them, remove the ones with the pattern "s__". These lines are then appended using >> operator in outputfile, so that the lines added before are not overwritten.

This is a very simple approach to the problem. For sure there are other solutions in terms of performances (maybe awk works better in case of huge files) and maybe more elegant than this one.

| improve this answer | |

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.