使用sed或awk在文件中查找和追加具有相同ID的行

时间:2013-04-19 12:05:31

标签: design-patterns sed awk

我有一些文件格式为{ 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的最佳方法。

4 个答案:

答案 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 +