可以在 sed 中使用反向引用作为替换值吗?

可以在 sed 中使用反向引用作为替换值吗?

源文件:

Linux 2.6.32-754.18.2.el6.x86_64 (myhostname)  03/24/2020      _x86_64_        (64 CPU)
07:32:01 PM      57     25.79      0.00      4.99      0.00      0.00      0.00      0.02      0.00     69.20
07:32:01 PM      58     26.38      0.00      3.43      0.00      0.00      0.00      0.02      0.00     70.17
07:32:01 PM      59     24.49      0.00      8.73      0.00      0.00      0.00      0.03      0.00     66.75
07:32:01 PM      60     20.31      0.00      5.60      0.00      0.00      0.00      0.02      0.00     74.08
07:32:01 PM      61     20.08      0.00      4.09      0.00      0.00      0.00      0.02      0.00     75.81
07:32:01 PM      62     21.33      0.00      5.23      0.00      0.00      0.00      0.02      0.00     73.42
07:32:01 PM      63     18.49      0.00      4.04      0.00      0.00      0.00      0.02      0.00     77.45

Average:        CPU      %usr     %nice      %sys   %iowait    %steal      %irq     %soft    %guest     %idle
Average:        all     24.02      0.00      5.23      0.07      0.00      0.00      0.23      0.00     70.45

期望的输出:

myhostname        64 CPU     24.02      0.00      5.23      0.07      0.00      0.00      0.23      0.00     70.45

我能够从第一个字符串中提取所需的值:

sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|p}' test.txt
myhostname 64 CPU

但我不知道如何用它来替换。

我知道有其他(perl/awk)方法可以满足需要,但我正在寻找sed解决方案

更新: 唉,评论中的两条建议都没有给我想要的输出

[14]labuser@labhost:~> sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|;h;};${H;x;s/\n.*all//;p;}' test.txt
isgmwapp6n1 64 CPU

[14]user@labhost:~> sed -n '1h;${H;x;s/.*(\([^)]*\)).*(\([^)]*\))\n.*all/\1 \2/p;}' test.txt
[14]user@labhost:~/>
[14]user@labhost:~> sed --version |head -1
GNU sed version 4.2.1
[14]user@labhost:~> cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.10 (Santiago)

更新2第三个也没有给出输出:( 附加屏幕截图 截屏

更新3我发现第一个建议的解决方案不起作用只是因为文件的最后一行是换行符。因此,我能够通过以下方式满足需要:

 sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|;h;};/Average.*all/{H;x;s/\n.*all//;p;}' test.txt

@mosvy,非常感谢您的帮助。如果您将上述内容发布为答案,我会接受它。

答案1

sed -n '1h;/Average.*all/{H;x;s/.*(\([^)]*\)).*(\([^)]*\))\n.*all/\1 \2/p;}' /tmp/jeg

应该适用于任何版本的 sed。

第一行的命令h将其内容复制到“保留空间”。

然后在最后一行(匹配的那个/Average.*all/,不是$因为文件末尾可能包含额外的空行),H;x;(附加到保留空间+交换保留和模式空间)将在其前面添加第一行,然后将s/../../p修剪删除不需要的东西并打印出来。

相关内容