我有一个以下格式的文本文件。每行具有可变数量的列。
文件:
gi|269201691|ref|YP_003280960.1| chromosomal replication initiation protein gi|57651109|ref|YP_184912.1| chromosomal replication initiation protein % 1 0.0 2296 100.0
gi|269201692|ref|YP_003280961.1| DNA polymerase III subunit beta gi|57651110|ref|YP_184913.1| DNA polymerase III subunit beta % 1 0.0 1964 100.0
生成的文件应如下所示:
gi|269201691|ref|YP_003280960.1| gi|57651109|ref|YP_184912.1| % 1 0.0 2296 100.0
gi|269201694|ref|YP_003280963.1| gi|57651112|ref|YP_184915.1| % 1 0.0 1767 100.0
以下代码有助于使用“ref”模式查找每一行中的列。
awk '{for (i=1;i<=NF;i++) if ($i ~ /ref/) print $i }'
关于如何做同样的想法?
答案 0 :(得分:1)
我假设您的新行在您的帖子中被破坏,并且您的输入文件实际上每行只有一个条目。在这种情况下,我认为这样做你想要的:
awk -F '[|%]' '{printf("%s|%d|%s|%s|",$1,$2,$3,$4);if($6)printf(" %%%s",$6);printf("\n")}'
编辑:好的,根据新的行号,您想要的可能是:
awk -F '[|%]' '{printf("gi|%d|ref|%s|gi|%d|ref|%s| %%%s\n",$2,$4,$6,$8,$10)}'
对于您的示例,这会为我生成以下输出
gi|269201691|ref|YP_003280960.1|gi|57651109|ref|YP_184912.1| % 1 0.0 2296 100.0
gi|269201692|ref|YP_003280961.1|gi|57651110|ref|YP_184913.1| % 1 0.0 1964 100.0
这可以通过手动将字段分隔符设置为|来实现要么 %。因此,描述中可变数量的单词不再是问题,我们可以直接索引我们想要的字段。
答案 1 :(得分:0)
这可能适合你(GNU sed):
sed 's/\(.*|.*|.*|.*|\)\(.*\)\(\S\+|.*|.*|.*|\)\2%/\1\3%/' file
如果输入文件有多行记录:
sed 'N;s/\n//;s/\(.*|.*|.*|.*|\)\(.*\)\(\S\+|.*|.*|.*|\)\2%/\1\3%/' file
答案 2 :(得分:0)
这是使用GNU awk
的一种方式:
awk 'BEGIN { OFS=FS="|" } { for (i=1; i<=NF; i++) if ($i ~ / gi$/) $i = " gi"; if (i = NF) sub(/.*%/," %",$i) }1' file.txt
这是使用GNU sed
的一种方式:
sed 's/|[^|]* gi|/| gi|/; s/\(.*|\).*\(%.*\)/\1 \2/' file.txt
结果:
gi|269201691|ref|YP_003280960.1| gi|57651109|ref|YP_184912.1| % 1 0.0 2296 100.0
gi|269201692|ref|YP_003280961.1| gi|57651110|ref|YP_184913.1| % 1 0.0 1964 100.0