С perl
:
perl -pe 's/\bH\b\K/++$i/e' file
Вы можете заменить -pe
на -pi.back -e
для редактирования на месте с оригиналом, сохраненным как file.back
или -pi -e
для отсутствия резервной копии.
вот один подход:
$ awk '$2!=old && NR>1 {for (i=1;i<=NF;i++) printf a[old","i]" "; print"";} {old=$2;for (i=1;i<=NF;i++) {if (a[$2","i]=="." || a[$2","i]=="") a[$2","i]= $i}} END{for (i=1;i<=NF;i++) printf a[old","i]" "; print"";}' file
chr1 45162 A . C T
chr1 45257 A . . T
chr1 45413 A . . T
chr1 46844 A . C .
chr1 72434 A G . .
chr1 72515 A . C T
chr1 77689 A G . .
$ 2! = Old && NR> 1 {для (i = 1; I <= NF; i ++) printf [старый "," я] ""; Печать «»;}
После первой строки, на каждый раз, когда мы столкнулись с новым значением для второго столбца, распечатайте результаты предыдущего значения.
старый = $ 2; для (i = 1; i <= nf; i ++) {если (a [$ 2 "," I] == ".« || A [$ 2 »,« I] == » ) А [$ 2 "," I] = $ i}
Обновите массив A
со значением из текущей строки.
GNU awk
имеет хорошие 2-D массивы. Для совместимости, однако, я использую POSIX-совместимую замену.
Конец {для (i = 1; i <= nf; i ++) printf [старый "," я] ""; Печать «»;}
После последней строки распечатайте информацию для последнего раздела.
Еще один вариант для несортированных строк:
awk '{
k[$2]=$1;
for(i=3;i<7;i++){
if(l[$2,i]=="." || l[$2,i]=="")
l[$2,i]=$i;
}
}
END{
for(n in k){
printf("%s %s ",k[n],n);
for(m=3;m<7;m++)
printf("%s ", l[n,m]);
print "";
}
}' file
Краткое объяснение:
Просматривая файловые скрипты делаем два assotiative массива: k
с полем#2
в качестве индекса и l
с индексом полем#2,Next_fields_number
. После передачи всех строк в файле скрипт начинает два цикла для вывода 1-го массива + поля из 2-х.
A Perl
Решение:
$ perl -anle '
for (2..$#F) {
$h{join(" ",@F[0..1])}->{$_} ||= $F[$_];
$h{join(" ",@F[0..1])}->{$_} = $F[$_] if $F[$_] ne ".";
}
END { print "$_ @{$h{$_}}{sort keys %{$h{$_}}}" for sort keys %h }
' file
chr1 45162 A . C T
chr1 45257 A . . T
chr1 45413 A . . T
chr1 46844 A . C .
chr1 72434 A G . .
chr1 72515 A . C T
chr1 77689 A G . .