I have a simple question but I could not figure it out.
I have a file that I want to print all the lines that DO NOT match the condition I specify in the awk if condition. But I can just get to print the condition, how the other would work?
This is my code:
awk '{if ($18==0 && $19==0 && $20==0 && $21==0) print $0}' file
I also tried this:
awk '{if !($18==0 && $19==0 && $20==0 && $21==0) print $0}' file
But the second one doesn't work, any help is appreciated. Thank you.
Here you can do:
awk '$18+$19+$20+$21!=0' file
print $0 is not needed, since its default action.
The negation (!) needs to be inside the parentheses:
awk '{if (!($18==0 && $19==0 && $20==0 && $21==0)) print $0}' file
And we add another set inside to wrap everything.
(FYI, if you had given how it "didn't work" (i.e., a syntax error on !, that would have been more helpful. Please remember to include error messages or symptoms of something not working for future questions!)
You could also reverse your conditional statement:
you want the opposite of :
awk '{if ($18==0 && $19==0 && $20==0 && $21==0) print $0}' file
Which can either be :
awk '{if ($18!=0 || $19!=0 || $20!=0 || $21!=0) print $0}' file
or
awk '{if (!($18==0 && $19==0 && $20==0 && $21==0)) print $0}' file
Example :
!cat file
A 0 0 0
B 1 1 1
C 1 0 1
awk '$2+$3+$4!=0' file
B 1 1 1
C 1 0 1
awk '{if ($2!=0 || $3!=0 || $4!=0) print $0}' file
B 1 1 1
C 1 0 1
awk '{if (!($2==0 && $3==0 && $4==0)) print $0}' file
B 1 1 1
C 1 0 1
awk '{if (!($2==0 || $3==0 || $4==0)) print $0}' file
B 1 1 1
Related
I want to modify this command and create a command to filter rows with "val" flag and more than 2 "PASS".
any suggestion?
this command can work only with one PASS:
awk '{if(($5=="val") && ($0 ~ /PASS/ )) {print $0}}' sample.vcf
Assuming $5 is the flag field:
awk '{if(($5=="val") && ($0 ~ /^.*PASS.*PASS.*$/ )) {print $0}}' sample.vcf
BTW {if(($5=="val") && ($0 ~ /PASS/ )) {print $0}} will not match any lines since if $5 == "val" $0 will never ~ /PASS/
I would like to print some specific parts of a results with awk, after multiple pattern selection.
What I have is (filetest):
A : 1
B : 2
I expect to have:
1 - B : 2
So, only the result of the first row, then the whole second row.
The dash was added by me.
I have this:
awk -F': ' '$1 ~ /A|B/ { printf "%s", $2 "-" }' filetest
Result:
1 -2 -
And I cannot get the full second row, without failing in showing just the result of the first one
awk -F': ' '$1 ~ /A|B/ { printf "%s", $2 "$1" }' filetest
Result:
1 - A 2 - B
Is there any way to print in the same line, exactly the column/row that I need with awk?
In my case R1C2 - R2C1: R2C2?
Thanks!
This will do what you are expecting:
awk -F: '/^A/{printf "%s -", $2}/^B/{print}' filetest
$ awk -F: 'NR%2 {printf "%s - ", $2; next}1' filetest
1 - B : 2
You can try this
awk -F: 'NR%2==1{a=$2; } NR%2==0{print a " - " $0}' file
output
1 - B : 2
I'd probably go with #jas's answer as it's clear, simple, and not coupled to your data values but just to show an alternative approach:
$ awk '{printf "%s", (NR%2 ? $3 " - " : $0 ORS)}' file
1 - B : 2
tried on gnu awk
awk -F':' 'NR==1{s=$2;next}{FS="";s=s" - "$0;print s}' filetest
I have a CSV file named as "awk_column_select_test.csv"
a,b,c
0.2,0.4,0.5
0.3,0.6,0.7
0.4,0.8,0.9
I was trying to write an awk code to select the rows where either column 1 or column 2 or column 3 is great than 0.5.
My awk program, named "awk_select_column_test.awk" looks like this:
#!/usr/bin/awk -f
BEGIN {FS=","; cutoff="0.5"}
{$1 > cutoff || $2 > cutoff || $3 > cutoff}
END {print}
Then, I tried to run on command line using:
awk -f awk_select_column_test.awk awk_column_select_test.csv
I got the following output with only 1 row:
0.4,0.8,0.9
However, I was hoping to get 2 rows like this:
0.3,0.6,0.7
0.4,0.8,0.9
You have extra curly brackets {} and END block print last line, the logic is all right.
#!/usr/bin/awk -f
BEGIN {FS=","; cutoff=0.5}
NR>1 && ($1 > cutoff || $2 > cutoff || $3 > cutoff){print}
This can be written, also
#!/usr/bin/awk -f
BEGIN {FS=","; cutoff=0.5}
NR>1 && ($1 > cutoff || $2 > cutoff || $3 > cutoff)
I want to select 2 fields and out put them to a file:
field$1 I want to select all if it = # symbol (for email)
field$2 I want to select if it = certain character length ie. 40.
only output if both requirements are met, how to do this in awk or sed?
I was using this:
awk -F: '/\#/ {print $1 ":" $2 }' test.txt > file_output.txt
however the # is for both $1 and $2 which is not what i want.
Thanks,
Edit: here is an example (in bold)
email#some.com:123456789123456789123456789:blah:blah:blah
ignore:1234#56789
output needed:
email#some.com:123456789123456789123456789
you can use this;
awk -F: '{if ($1 ~ /\#/ && length($2) == 40) print $1 ":" $2 }' test.txt > file_output.txt
Test;
sample file
$ cat t
user#host1:0123456789012345678901234567890123456789
user#host2:0123456789012345678901234567890123456789
userhost3:0123456789012345678901234567890123456789
user#host4:012345677
awk output;
$ awk -F: '{if ($1 ~ /\#/ && length($2) == 40) print $0 }' t
user#host1:0123456789012345678901234567890123456789
user#host2:0123456789012345678901234567890123456789
I have got following two codes:
nut=`awk "/$1/{getline; print}" ids_lengths.txt`
and
grep -v '#' neco.txt |
grep -v 'seq-name' |
grep -E '(\S+\s+){13}\bAC(.)+CA\b' |
awk '$6 >= 49 { print }' |
awk '$6 <= 180 { print }' |
awk '$4 > 1 { print }' |
awk '$5 < $nut { print }' |
wc -l
I would like my script to replace "nut" at this place:
awk '$4 < $nut { print }'
with the number returned from this:
nut=`awk "/$1/{getline; print}" ids_lengths.txt`
However, $1 in code just above should represent not column from ids_lengths.txt, but first column from neco.txt! (similiarly as I use $6 and $4 in main code).
A help how to solve these nested awks will definitely be appreciated:-)
edit:
Line of my input file (neco.txt) looks like this:
FZWTUY402JKYFZ 2 100.000 3 11 9 4.500 7 0 0 0 . TG TGTGTGTGT
The biggest problem is that I want to filter those lines that have in the fifth column number less than number, which I get from another file (ids_lengths.txt), when searching with first column (e.g. FZWTUY402JKYFZ). That's why I put "nut" variable in my draft script :-)
ids_lengths.txt looks like this:
>FZWTUY402JKYFZ
153
>FZWTUY402JXI9S
42
>FZWTUY402JMZO4
158
You can combine the two grep -v operations and the four consecutive awk operations into one of each. This gives you useful economy without completely rewriting everything:
nut=`awk "/$1/{getline; print}" ids_lengths.txt`
grep -E -v '#|seq-name' neco.txt |
grep -E '(\S+\s+){13}\bAC(.)+CA\b' |
awk -vnut="$nut" '$6 >= 49 && $6 <= 180 && $4 > 1 && $5 < nut { print }' |
wc -l
I would not bother to make a single awk script determine the value of nut and do the value-based filtering. It can be done, but it complicates things unnecessarily — unless you can demonstrate that the whole thing is a bottleneck for the performance of the production system, in which case you do work harder (though I'd probably use Perl in that case; it can do the whole lot in one command).
Approximately:
awk -v select="$1" '$0 ~ select && FNR == NR { getline; nut = $0; } FNR == NR {next} $4 > 1 $5 < nut && $6 >= 49 && $6 <= 180 && ! /#/ && ! /seq-name/ && $NF ~ /^AC.+CA$/ {count++} END {print count}' neco.txt ids_lengths.txt
The regex will need to be adjusted to something that AWK understands. I can't see how the regex matches the sample data you provided. Part of the solution may be to use a field count as one of the conditions. Perhaps NF == 13 or NF >= 13.
Here's the script above broken out on multiple lines for readability:
awk -v select="$1" '
$0 ~ select && FNR == NR {
getline
nut = $0;
}
FNR == NR {next}
$4 > 1
$5 < nut &&
$6 >= 49 &&
$6 <= 180 &&
! /#/ &&
! /seq-name/ &&
$NF ~ /^AC.+CA$/ {
count++
}
END {
print count
}' ids_lengths.txt neco.txt