2

我有一些格式为 { 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

4 回答 4

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

除非您的实际文件非常大,否则这会很好,在这种情况下,缓冲方法会更好:

$ 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
于 2013-04-19T12:14:00.737 回答
0

用法awk -f app.awk file.dat file.dat

应用程序.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
}
于 2013-04-19T12:17:32.120 回答
0
awk '$2=="F"{$3=s[$1];$4=n[$1]}{s[$1]=$3}n[$1]=$4' file

这将保留顺序,前提P是行在行之前F。感谢 sudo_O +

于 2013-04-19T12:31:03.093 回答
0

如果顺序无关紧要,并且每个 P 都有匹配的 F 行,则可以:

grep ' P ' file; grep ' P ' file | sed 's/ P / F /'
于 2013-04-19T12:14:54.097 回答