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

修正する: ああ、コメントの2つの提案のどれも私が望む結果を得ませんでした。

[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)

アップデート23番目の項目も出力を提供しません。 :(添付のスクリーンショット スクリーンショット

アップデート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

おすすめ記事