0

Source file:

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

Desired output:

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

I was able to extract required values from first string:

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

But I don't know how to use it for replacement.

I'm aware about other (perl/awk) ways to do the needfull but I'm looking for sed solution

Update: Alas both suggestions from comment haven't given me the desired output

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

Update2 Third one also gives no output :( Attaching screenshot screenshot

Update3 I found out that first suggested solution don't work just because the last line of file is newline. Thus I was able to the needful via the following:

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

@mosvy, many thanks for you help. if you post the above as answer I gonna accept it.

5
  • What's the problem with awk? Even busybox has awk. Anyways, try sed -n '1{s|^[^(]*(\([^)]*\))[^(]*(\([^)]*\)).*|\1 \2|;h;};${H;x;s/\n.*all//;p;}'
    – mosvy
    Mar 27, 2020 at 1:38
  • 1
    Or, better: sed -n '1h;${H;x;s/.*(\([^)]*\)).*(\([^)]*\))\n.*all/\1 \2/p;}'
    – mosvy
    Mar 27, 2020 at 1:45
  • @mosvy pls see update Mar 27, 2020 at 13:06
  • @mosvy Attached screenshot Mar 27, 2020 at 15:44
  • Doh, I didn't think of empty trailing lines, my bad.
    – mosvy
    Mar 27, 2020 at 17:53

1 Answer 1

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

should work in any version of sed.

The h command on the first line copies its content to the "hold space".

Then on the last line (the one matching /Average.*all/, not $ because the file may contain extra empty lines at the end), H;x; (append to the hold space + exchange hold and pattern space) will prepend the first line to it, and then the s/../../p will trim it of unneeded stuff and print it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.