我遇到类似last time的问题。
这次我的header
文件看起来像是:
>random header 2
>random header name1
和我的basefile
>random header name1
wonderfulstringwhatsoevergoeson
>random header 2
someotherline
现在的目标是,得到以下结果:
someotherline
wonderfulstringwhatsoevergoeson
所以我希望匹配后的basefile
。 (只有这一个,而不是标题)
重要的是,它应保持header
的顺序。
排序不起作用,因为它将保持字母顺序,这不应该发生。
我无法弄清楚,grep如何比较两个文件并在匹配后给出该行:/
答案 0 :(得分:3)
这将为您完成这项工作:
awk 'FNR==NR
{
a[$0]=FNR;i=FNR;next
}
($0 in a)
{
t=$0;
getline;b[a[t]]=$0
}
END
{
for(k=1;k<=i;k++)print b[k]
}' head base
答案 1 :(得分:2)
这应该这样做:
awk '
{ recs[NR] = $0 } # store the header lines in 1->(NR-FNR) and the basefile lines in ((NR-FNR)+1)->NR
END {
for (hdrNr=1; hdrNr<=(NR-FNR); hdrNr++) {
hdr = recs[hdrNr]
for (lineNr=(NR-FNR)+1; lineNr<=NR; lineNr++) {
line = recs[lineNr]
if (line == hdr) {
print recs[lineNr+1]
}
}
}
}
' header basefile
跟进@Vijays只是将匹配行存储在按读取标题顺序索引的数组中的想法,这里是如何在没有getline的情况下执行此操作,没有不必要的变量,使用有意义的变量名称,并且不打印每个不匹配标题的空白行:
awk '
NR==FNR { hdr2nr[$0] = FNR; next }
hdrNr { hdrNr2line[hdrNr] = $0 }
{ hdrNr = hdr2nr[$0] }
END {
for(hdrNr=1; hdrNr<=(NR-FNR); hdrNr++)
if (hdrNr in hdrNr2line)
print hdrNr2line[hdrNr]
}
' header basefile
假设给定的标题只能在basefile中出现一次。
答案 2 :(得分:1)
试试这个bash one-liner:
while read line; do match=$(sed -n "/$line/{ n;p}" basefile); echo $match; done < 'header'
当你的基本文件总是有一个相应标题的行定义时,这将有效。
头:
sat:~# cat header
>random header 2
>random header name1
basefile:
sat:~# cat basefile
>random header name1
wonderfulstringwhatsoevergoeson
>random header 2
someotherline
输出:
sat:~# while read line; do match=$(sed -n "/$line/{ n;p}" basefile);echo $match; done < 'header'
someotherline
wonderfulstringwhatsoevergoeson
答案 3 :(得分:1)
将basefile
读入%h
哈希,然后按照header
文件中指定的键顺序
perl -ne 'BEGIN{ open $F,pop or die $!; %h=<$F> } print $h{$_}' header basefile
答案 4 :(得分:1)
这可能适合你(GNU sed):
sed -r 'N;s/^(.*)\n(.*)/s|^\1$|\2|/' base_file | sed -f - header_file
将base_file
转换为sed
脚本并针对header_file
运行。