我有一些文件格式为{ ID Type Size Nodes },例如:
1234 P 1 56
2212 P 2 45-46
1234 F
2567 P 3 90,99,101
2212 F
2567 F
其中每个P型线只有一个匹配的F型线具有相同的ID,并且每对的ID都不同。
我希望能够搜索文件,并且对于P类型的每一行,找到具有相同ID的匹配类型F行,然后从P类型行追加“大小”和“节点”值。
这可能吗? 我可以想一下使用关联数组在bash中做到这一点的方法,但我希望sed / awk可能会有类似这样的东西的一些漂亮的小技巧,但我没有正确的单词来搜索/看它起来。我知道你可以保留模式,我的主要问题是找出搜索不同ID的最佳方法。
答案 0 :(得分:2)
如果您不介意更改最简单方法的行顺序:
$ awk '$2=="P"{print;$2="F";print}' file
1234 P 1 56
1234 F 1 56
2212 P 2 45-46
2212 F 2 45-46
2567 P 3 90,99,101
2567 F 3 90,99,101
这是在F
行出现后P
行更改的顺序(P
行的顺序未更改)。
如果您不希望订单发生变化,但保证首先发生P
行:
$ awk '$2=="P"{a[$1]=$3FS$4}{print $1,$2,a[$1]}' file
1234 P 1 56
2212 P 2 45-46
1234 F 1 56
2567 P 3 90,99,101
2212 F 2 45-46
2567 F 3 90,99,101
另外,你有两种方法,缓冲或传递文件两次,这是两次传递解决方案:
$ awk '$2=="P"{a[$1]=$3FS$4}FNR!=NR{print $1,$2,a[$1]}' file file
1234 P 1 56
2212 P 2 45-46
1234 F 1 56
2567 P 3 90,99,101
2212 F 2 45-46
2567 F 3 90,99,101
除非你的actaul文件非常大,否则这样会很好,在这种情况下,缓冲方法会更好:
$ awk '$2=="P"{a[$1]=$3FS$4}{b[NR]=$0;k[NR]=$1}END{for(i=1;i<=NR;i++)print b[i],a[k[i]]}' file
1234 P 1 56
2212 P 2 45-46
1234 F 1 56
2567 P 3 90,99,101
2212 F 2 45-46
2567 F 3 90,99,101
答案 1 :(得分:0)
如果订单无关紧要且每个P都有匹配的F行,您可以:
grep ' P ' file; grep ' P ' file | sed 's/ P / F /'
答案 2 :(得分:0)
用法awk -f app.awk file.dat file.dat
<强> app.awk:强>
FNR==NR && $2 == "P" {
id=$1
$1=$2=""
aux[id]=$0
}
FNR!=NR && $2 == "F" {
$0 = $0 aux[$1]
$1=$1
}
FNR!=NR {
print
}
答案 3 :(得分:0)
awk '$2=="F"{$3=s[$1];$4=n[$1]}{s[$1]=$3}n[$1]=$4' file
如果P
行在F
行之前提供,则会保留订单。感谢sudo_O +