Цикл AWK по нескольким столбцам
Представьте, что у меня следующая ситуация (несколько столбцов и строк):
1/1:123:121 TAB 0/0:1:21 TAB 1/1:12:14
0/1:12:23 TAB 0/1:12:15 TAB 0/0:123:16
0/0:3:178 TAB 1/1:123:121 TAB 1/1:2:28
Хотелось бы, чтобы awk перебирал каждый столбец и записывал новый вывод при следующих условиях:
ЕСЛИ первое поле (разделенное ":") равно 1/1 ИЛИ 0/0,
затем напишите "НА" ВКЛАДКА "НА"
ЕЩЕ
впишите два числа в следующие поля: «Номер 1» ВКЛАДКА «Номер 2». Разделитель между столбцами должен быть TAB.
Таким образом, желаемый результат из приведенного выше примера будет:
NA TAB NA TAB NA TAB NA TAB NA TAB NA
12 TAB 23 TAB 12 TAB 15 TAB NA TAB NA
NA TAB NA TAB NA TAB NA TAB NA TAB NA
Ниже приведен мой текущий код, который работает для первого столбца, но я не знаю, как заставить его работать для ВСЕХ столбцов в файле.
awk '{split($0,a,":"); print a[1]"\t"a[2]"\t"a[3]}' |
awk -F"\t" '{
if ($1 == "0/0" || $1 == "1/1")
print $1="NA", $2="NA"
else
print $2"\t"$3
}'
Есть идеи, как этого можно достичь?
Заранее большое спасибо, Джордж.
4 ответа
You may use this
awk
:
awk -v OFS='\t' -F '[:\t]' '{
s = ""
for (i=1; i<=NF; i+=3)
s = (s == "" ? "" : s OFS) ($i == "0/0" || $i == "1/1" ? "NA" OFS "NA" : $(i+1) OFS $(i+2))
print s
}' file
NA NA NA NA NA NA
12 23 12 15 NA NA
NA NA NA NA NA NA
If I'm understanging your notation of
TAB
correctly, would you please try:
awk -F"\t" '{
for (i = 1; i <= NF; i++) {
split($i, a, ":")
if (a[1] == "0/0" || a[1] == "1/1") a[2] = a[3] = "NA"
printf "%s\t%s%s", a[2], a[3], i == NF ? "\n" : "\t"
}
}' input_file
where
input_file
looks like:
1/1:123:121 0/0:1:21 1/1:12:14
0/1:12:23 0/1:12:15 0/0:123:16
0/0:3:178 1/1:123:121 1/1:2:28
and the output:
NA NA NA NA NA NA
12 23 12 15 NA NA
NA NA NA NA NA NA
A sed solution:
sed 's~\(0/0\|1/1\)[0-9:]\+~NA\tNA~g; s~./.:\([0-9]\+\)\:\([0-9]\+\)~\1\t\2~g' dat.tab
NA NA NA NA NA NA
12 23 12 15 NA NA
NA NA NA NA NA NA
first substitution NAs fields beginning with '0/0' or '1/1'
second substitution isolates and emits the trailing colon separated numbers from the field
(did tidy up output spacing)
One possible solution:
awk '{ for(i=1; i<=NF; i++){split($i,a,","); if (a[1] == "0/0" || a[1] == "1/1") {printf " ""NA"" ""NA"} else {printf " "a[2]" "a[3]}} print""}' | cut -d " " -f2- > Test.txt