我想比较和替换unix中不同行中的字符串
例如,我有一个文件,每行有两个单词
<a> <b> <d> <e> <b> <c> <c> <e>
如果任何行的第二个字与任何其他行的第一个字匹配,则该行的第二个字应该被匹配行的第二个字替换,并且它应该迭代直到该行的第二个字与另一个行的第一个字之间不匹配
我需要结果
<a> <e> <b> <e> <c> <e> <d> <e>
我是unix的新手,并不知道如何实现它.任何人都可以提出建议或解释我们如何做到这一点
对于递归下降解决方案来说,这非常明显:
$cat tst.awk function descend(node) {return (map[node] in map ? descend(map[node]) : map[node])} { map[$1] = $2 } END { for (key in map) print key,descend(key) } $awk -f tst.awk file <a> <e> <b> <e> <c> <e> <d> <e>
如果输入中的无限递归是可能的,那么这是一种方法,它将在递归开始之前作为第二个字段打印出最后一个节点并在其旁边放置一个“*”,以便您知道它正在发生:
$cat tst.awk function descend(node,child,descendant) { stack[node] child = map[node] if (child in map) { if (child in stack) { descendant = node "*" } else { descendant = descend(child) } } else { descendant = child } delete stack[node] return descendant } { map[$1] = $2 } END { for (key in map) print key,descend(key) }
.
$cat file <w> <w> <x> <y> <y> <z> <z> <x> <a> <b> <d> <e> <b> <c> <c> <e> $awk -f tst.awk file <w> <w>* <x> <z>* <y> <x>* <z> <y>* <a> <e> <b> <e> <c> <e> <d> <e>
如果您需要输出顺序以匹配输入顺序和/或打印重复行两次,请将脚本的底部2行更改为:
{ keys[++numKeys] = $1; map[$1] = $2 } END { for (keyNr=1; keyNr<=numKeys; keyNr++) { key = keys[keyNr] print key,descend(key) } }