#CHROM POS T1 T10 T11 T12 T13 T2 T3 T4 T5 T6 T106 T107 T108 T109 T110 T112 T114 T116 T120 T122 T125 T128 T129 T130
Aradu.A01 300806 H B B B B B B B H B B H B B B B B B B B B B B
Aradu.A01 386907 A A A A A A A A A A A A H A A A A A H A A A A
Aradu.A01 463100 B B A A A A A H B A A H H H H H B A B A H H A
Aradu.A01 471639 A A A A H A A H A A H A A A A A H A A A H A A
Aradu.A01 644024 H B B B B B B B H H B H H B B B H B H B B B H
Aradu.A01 756331 H H H H H H H H B B B H H H H H B H H H B B B
Aradu.A01 768081 A A A A A A A A A A A A A A A A A A A A A A A
Aradu.A01 783066 A A H A H H A A A A H A H A A A A A A H A A H
Aradu.A01 812865 H B H H H H H H H H H H H H H H B B H H B B H
Aradu.A01 976731 A H A H H A H H A H H A H H A A H A H A A A H
Aradu.A01 1089311 A H H H H A A A H A H B A H H H H H A A H H H
Aradu.A01 1089991 A A A H A A H A A H A A A A H A A A A A A A H
Aradu.A01 1113781 H H H H H H H A H H H H H H A H H A H A H H H
Aradu.A01 1160441 B B B B B B H B H B B B B B H B B B B B B B B
Aradu.A01 1638873 B H B B H B B B B B B B H H H B B B B B H B B
Aradu.A01 1638907 B H B B H B B B H B B B H H H B B B B B H B B
Кто-нибудь, пожалуйста, помогите мне с кодом awk, который может получить только строки, в которых есть поля с буквой "A" а "Б" в нем? Строки с
1) только «А» и «Н»,
2) только "B" и "H" НЕ учитываются.
Каждый должен иметь как A, так и B. Если H также присутствует с A и B, тогда также следует учитывать строку. Таким образом, необходимо иметь только строки с «A» и «B», и если «H» присутствует вместе с «A» и «B», то эту строку также следует учитывать:
NR>1 {for(i=3;i<=NF;i++)
{ if ( $i ~ "A" && $i ~ "B" && $1 ~ "H" ) ;
} ## if ;
## for loop is done
print ;
Приведенный выше код возвращает результат файл в качестве входного файла. }
Не решение awk
, но этот grep
, похоже, помогает:
egrep '^Aradu\.[A-Z][0-9]{2}.*A.*B|^Aradu\.[A-Z][0-9]{2}.*B.*A' aradu
Aradu.A01 463100 B B A A A A A H B A A H H H H H B A B A H H A
Aradu.A01 1089311 A H H H H A A A H A H B A H H H H H A A H H H
Где ] aradu
- ваш пример файла.
Правка, разбивка регулярного выражения:
^ Aradu \. [A-Z] [0-9] {2}
= Строки, начинающиеся с "Aradu", за которыми следует литерал "." за которым следует любой символ верхнего регистра, за которым следует любое целое число два раза.
. * A. * B
= За ним следует любой символ, любое количество раз (.*
), за которым следует литерал «A», за которым следует литерал «B»
|
= логическое или.
(То же начало выражения до)
. * B. * A
= Любой символ, повторяющийся любое количество раз, за которым следует литерал 'B', за которым следует буквальный "А".
grep
не имеет оператора &&
(логического и), это самый близкий (насколько мне известно) вы можете найти строку с помощью A && B | | B&&A
.
У вашего скрипта есть несколько проблем:
H
, когда не имеет значения, появляется ли H
или нетH
в $1
(первое поле), каждый раз в циклеif
не имеет никакого действия. Тест print
достигается всегда, для каждой строки. Чтобы отследить, присутствуют ли A и B в одной строке (в разных полях), можно использовать переменную для каждой:
NR>1 {
#beginning of line - no As or Bs seen yet
A=0
B=0
#looping over all fields except the first two
#break as soon as both A and B found
for(i=3; A*B == 0 && i<=NF; i++) {
if ( $i ~ "A" ) A=1
if ( $i ~ "B" ) B=1
}
#print line if A and B were found
if (A && B) print
}