grep this and this2 and that and that2
I'm probably overlooking something obvious here. I've found a number of pages which discuss
grep and logical AND but none seem to accomplish what I need. I have a script (which I cannot modify). It outputs (something like) the following: Code:
ViewAsString=[1.2.3.1:11|3] [1.2.3.1:11, 1.2.3.2:122, 1.2.3.8:123, 1.2.3.4:124] So I can do this Code:
'foo.sh | grep 1.2.3.1 | grep 1.2.3.2 | grep 1.2.3.4 | grep 1.2.3.8' Code:
foo.sh | awk '/1.2.3.1/ && /6.6.6.6/' |
I can't help you with grabbing exit codes, but the grep for number patterns works with the -e option.
Your code: Code:
'foo.sh | grep 1.2.3.1 | grep 1.2.3.2 | grep 1.2.3.4 | grep 1.2.3.8' Code:
'foo.sh | grep -e 1.2.3.1 -e 1.2.3.2 -e 1.2.3.4 -e 1.2.3.8' |
You have to force awk to return an exit code if the expression is not true:
Code:
foo.sh | awk '!(/1.2.3.1/ && /1.2.3.2/ && /1.2.3.4/ && /1.2.3.8/){exit 1}' |
Quote:
His string would also match e.g.: 1.213.1 ... back-slashes are our friends! Cheers, Tink |
I tried these test
Code:
$ echo '1 x'|grep -e 1 -e 2 |
Code:
grep -o "[1][.][2][.][3][.][1248]"|uniq | wc -w for uniq the repeated lines need to be adjacent else you can use Code:
grep -o "[1][.][2][.][3][.][1248]"|sort -u | wc -w |
Yes, grep's (and sed's) "-e" expressions (including regex combinations) act like OR, not AND.
Think about how it works. Each line is read in in sequence, and compared to all the expressions given. If it matches any of them, it returns it as output. Then the next line is read. So no, if the file must contain ALL of the given expressions, then a single grep can't handle it. You have to use awk, or another tool like perl or even shell scripting, that can keep track of what has and hasn't been found as it iterates through the file. It would generally also take something more complex than a short one-liner as well. Indeed Colucix's offering: Code:
It can be made to work, however, if the file is small enough to sit in memory, and you're using a compatible version of awk (i.e. gnu). Just redefine the record separator to null, which should make it treat the whole file as a single record. In which case I'd probably go with something more like this: Code:
But if the file is too large for the above, you'd have to a more complex run-through of each line in turn, setting a variable for each matched string, say, then testing those for final compliance at the end. Here's a proof of concept I just whipped up that appears to work, although it could undoubtedly be made much cleaner with a bit of effort. Code:
awk '/1[.]2[.]3[.]1/ { a=1 } ; /1[.]2[.]3[.]2/ { b=1 } ; /1[.]2[.]3[.]4/ { c=1 } ; /1[.]2[.]3[.]8/ { d=1 } END{ x=a+b+c+d ; if ( x == 4 ){ print "all 4 found" ; exit 0 } else print "something not found" ; exit 1 }' infile.txt |
Quote:
Code:
grep -o "[1][.][2][.][3][.][1248]"|sort -u |[ "$(wc -w)" -eq "4" ];echo $? |
All times are GMT -5. The time now is 11:40 AM. |