3

I have a pipe delimited file like below

TEST|RALPH|JACKSON|2|3|1
TEST|STEVE|PARKER|0|1|1
TEST|MARK|WOODS|0|1|1
TEST|DAVE|KNIGHT|1|3|1
TEST|JOHN|DOE|0|1|1

I want to filter the rows with non-zero value in columns 4,5 and 6 write it in a separate file.

Expected output

TEST|RALPH|JACKSON|2|3|1
TEST|DAVE|KNIGHT|1|3|1

I tried the following awk achieve this

awk -F "|" '$4 != 0 && $5 !=0 && $6 !=0' input.txt > output.txt

I would like to know if there is a better way to do this using awk.

  • 7
    That awk solution is perfectly fine and makes it clear what the intent is. Sometimes clarity of intent is as important as code efficiency. You could probably create a regex to match... but then someone would end up with the headache of understanding it at a later date! – Stephen Harris Mar 29 at 1:14
  • 1
    You can multiply them awk -F\| '$4 * $5 * $6'. – mosvy Mar 30 at 11:46
4

Your current approach is correct, clear, and works as advertised, there is no real need to change it.

However, if you wanted to test even more columns, say all columns after column 3, this could possibly lead to a somewhat long awk program (if there were many columns).

Another way to do that would be to use a loop:

$ awk -F '|' '{ for (i=4; i<=NF; ++i) if ($i == 0) next; print }' file
TEST|RALPH|JACKSON|2|3|1
TEST|DAVE|KNIGHT|1|3|1

This awk program tests the values of all columns after column 3 and skips the current line as soon as a column whose value is zero is found. If no zero is found, the current line is printed.

1
#!/usr/bin/python
import subprocess
k=open('k.txt','r')
for i in k:
    h=i.strip().split('|')
        if "0" not in h[-3:]:
            print "|".join(h)
output

python script.py

TEST|RALPH|JACKSON|2|3|1
TEST|DAVE|KNIGHT|1|3|1

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.