说我有一个file.txt
Position name1 name2 name3
2 A G F
4 G S D
5 L K P
7 G A A
8 O L K
9 E A G
我需要获得输出:
name1 name2 name3
2 2 7
4 7 9
7 9
输出每个名称,以及存在A或G
的位置编号在file.txt中,name1列在位置2中有A,在位置4和7中有G'因此在输出文件中:2,4,7列在name1下 ......等等
到目前为止我设计的策略(效率不高):一次读取一列,并在匹配发生时输出位置编号。然后,我将获得每列的结果,并使用r。
将它们组合在一起我相当确定使用awk或bash是一种更好的方法...赞赏的想法。
答案 0 :(得分:3)
$ cat tst.awk
NR==1 {
for (nameNr=2;nameNr<=NF;nameNr++) {
printf "%5s%s", $nameNr, (nameNr<NF?OFS:ORS)
}
next
}
{
for (nameNr=2;nameNr<=NF;nameNr++) {
if ($nameNr ~ /^[AG]$/) {
hits[nameNr,++numHits[nameNr]] = $1
maxHits = (numHits[nameNr] > maxHits ? numHits[nameNr] : maxHits)
}
}
}
END {
for (hitNr=1; hitNr<=maxHits; hitNr++) {
for (nameNr=2;nameNr<=NF;nameNr++) {
printf "%5s%s", hits[nameNr,hitNr], (nameNr<NF?OFS:ORS)
}
}
}
$ awk -f tst.awk file
name1 name2 name3
2 2 7
4 7 9
7 9
答案 1 :(得分:1)
保存以下脚本:
#!/bin/bash
gawk '{if( NR == 1 ) {print $2 >>"name1"; print $3 >>"name2"; print $4>>"name3";}}
{if($2=="A" || $2=="G"){print $1 >> "name1"}}
{if($3=="A" || $3=="G"){print $1 >> "name2"}}
{if($4=="A" || $4=="G"){print $1 >> "name3"}}
END{system("paste name*;rm name*")}' $1
为finder
。使finder成为可执行文件(使用chmod),然后执行:
./finder file.txt
注意:我使用了三个临时文件name1,name2和name3。您可以在方便时更改文件名。此外,这些文件将在最后删除。
修改:删除了gawk的BEGIN
部分。