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

관련 정보