可以在替换字符串中使用匹配的模式吗?

Luk*_*key 0 linux bash regex sed

我是正则表达式和 GNU sed 的新手。我有以下数据的匿名样本。

RED: 13905 16356 17457 18164 18447 21063 26924 27684 30111 30205
CERISE: 6221 6524 18250 24367 24462 29014
CARMINE: 39 49 53 81 95 99 105 106 109 134 195 226 260 350 383 393 397 414 417 435 439 478 488 516 521 535 596 599 614 621 628 630 632 635 785 786 810 836 837 841 852 855 953 1029 1104 1121 1122 1137 1148
VERMILLION: 23029
Run Code Online (Sandbox Code Playgroud)

我想用字符串开头的文本加上前缀 (</>) 替换第一个之后的每个空格,以便所需的输出是:

RED: 13905</>RED: 16356</>RED: 17457</>RED: 18164</>RED: 18447</>RED: 21063</>RED: 26924</>RED: 27684</>RED: 30111</>RED: 30205
CERISE: 6221</>CERISE: 6524</>CERISE: 18250</>CERISE: 24367</>CERISE: 24462</>CERISE: 29014
CARMINE: 39</>CARMINE: 49</>CARMINE: 53</>CARMINE: 81</>CARMINE: 95</>CARMINE: 99</>CARMINE: 105</>CARMINE: 106</>CARMINE: 109</>CARMINE: 134</>CARMINE: 195</>CARMINE: 226</>CARMINE: 260</>CARMINE: 350</>CARMINE: 383</>CARMINE: 393</>CARMINE: 397</>CARMINE: 414</>CARMINE: 417</>CARMINE: 435</>CARMINE: 439</>CARMINE: 478</>CARMINE: 488</>CARMINE: 516</>CARMINE: 521</>CARMINE: 535</>CARMINE: 596</>CARMINE: 599</>CARMINE: 614</>CARMINE: 621</>CARMINE: 628</>CARMINE: 630</>CARMINE: 632</>CARMINE: 635</>CARMINE: 785</>CARMINE: 786</>CARMINE: 810</>CARMINE: 836</>CARMINE: 837</>CARMINE: 841</>CARMINE: 852</>CARMINE: 855</>CARMINE: 953</>CARMINE: 1029</>CARMINE: 1104</>CARMINE: 1121</>CARMINE: 1122</>CARMINE: 1137</>CARMINE: 1148
VERMILLION: 23029
Run Code Online (Sandbox Code Playgroud)

我尝试了下面的内容,它从字面上解释了 ' ^.*: ' 并且与行的开头不匹配(我忽略了第一个空格也将暂时被替换的事实)。

sed 's/ /\<\\\>^.*: /g' inputfile

RED:<\>^.*: 13905<\>^.*: 16356<\>^.*: 17457<\>^.*: 18164<\>^.*: 18447<\>^.*: 21063<\>^.*: 26924<\>^.*: 27684<\>^.*: 30111<\>^.*: 30205
CERISE:<\>^.*: 6221<\>^.*: 6524<\>^.*: 18250<\>^.*: 24367<\>^.*: 24462<\>^.*: 29014
CARMINE:<\>^.*: 39<\>^.*: 49<\>^.*: 53<\>^.*: 81<\>^.*: 95<\>^.*: 99<\>^.*: 105<\>^.*: 106<\>^.*: 109<\>^.*: 134<\>^.*: 195<\>^.*: 226<\>^.*: 260<\>^.*: 350<\>^.*: 383<\>^.*: 393<\>^.*: 397<\>^.*: 414<\>^.*: 417<\>^.*: 435<\>^.*: 439<\>^.*: 478<\>^.*: 488<\>^.*: 516<\>^.*: 521<\>^.*: 535<\>^.*: 596<\>^.*: 599<\>^.*: 614<\>^.*: 621<\>^.*: 628<\>^.*: 630<\>^.*: 632<\>^.*: 635<\>^.*: 785<\>^.*: 786<\>^.*: 810<\>^.*: 836<\>^.*: 837<\>^.*: 841<\>^.*: 852<\>^.*: 855<\>^.*: 953<\>^.*: 1029<\>^.*: 1104<\>^.*: 1121<\>^.*: 1122<\>^.*: 1137<\>^.*: 1148<\>^.*: 
VERMILLION:<\>^.*: 23029
Run Code Online (Sandbox Code Playgroud)

那么是不是不能在替换字符串中使用正则表达式?我还有什么其他方法可以做到这一点?

谢谢,L

Tho*_*hor 5

使用重复替换:

sed -E ':a; s/^(([A-Z:]+).*)([0-9]+) /\1\3<\/>\2 /; ta'
Run Code Online (Sandbox Code Playgroud)

输出:

sed -E ':a; s/^(([A-Z:]+).*)([0-9]+) /\1\3<\/>\2 /; ta'
Run Code Online (Sandbox Code Playgroud)

评论版:

# Create a label we can jump to
:a

# This pattern will capture the front heading into group \2 and
# everything following that up-to number+space into group \1.
# The matched number is saved in group \3
s/^(([A-Z:]+).*)([0-9]+) /\1\3<\/>\2 /

# If the previous substitution was successful, repeat it
ta
Run Code Online (Sandbox Code Playgroud)