BASH 스크립트 - 출력을 읽고 값별로 분할

BASH 스크립트 - 출력을 읽고 값별로 분할

명령을 실행하고 해당 명령의 출력을 필터링한 다음 해당 출력의 결과를 읽고 주어진 요구 사항을 충족하는 부분만 인쇄하는 BASH 스크립트를 만들려고 합니다.

예를 들어:

출력이 다음과 같이 표시되도록 원래 명령의 출력을 줄였습니다.

Profile: 1
PsA of Profile 1: 13
PsL of Profile 1: 15
Profile: 2
PsA of Profile 2: 0
PsL of Profile 2: 0

각 프로필 섹션을 개별적으로 읽고 PsA 및 PsL 값이 0보다 큰 프로필 번호만 인쇄하는 BASH 스크립트를 작성하려고 합니다.

명확성을 위해 출력은 프로필 값만 필요하므로 이 예에서는 1이고 2는 삭제됩니다.

제가 하려는 작업 때문에 BASH 스크립트도 필요합니다.

나는 이 모든 것이 처음이고 완전히 붙어 있습니다. 도와주세요!

**편집** 명확성을 위해 변동성 프레임워크를 사용하려고 합니다. 현재 얻을 수 있는 구성 파일을 보고 있습니다. 정확한 출력은 다음과 같습니다.

Profile suggestion (KDBGHeader): WinXPSP3x86
PsActiveProcessHead           : 0x8055a158 (31 processes)
PsLoadedModuleList            : 0x80553fc0 (122 modules)
Profile suggestion (KDBGHeader): WinXPSP2x86
PsActiveProcessHead           : 0x8055a158 (31 processes)
PsLoadedModuleList            : 0x80553fc0 (122 modules)

나에게 필요한 것은 스크립트가 PsActiveProcessHead 및 PsLoadedModuleList(PsA 및 PsL), 특히 발견된 프로세스 및 모듈 수를 확인하고 괄호 안에 표시된 두 값이 모두 0보다 크면 프로필 제안을 인쇄하도록 하는 것입니다. 1개의 프로필 제안이 있을 수 있으며 그 이상일 수도 있습니다. 위에 나열된 모듈과 프로세스 0을 포함하는 발견된 프로필을 출력하려면 스크립트가 필요합니다.

명확하지 않은 원래 질문에 대해 사과드립니다. 더 간단하게 만들고 답변을 조정하려고 노력했지만 여전히 어려움을 겪고 있습니다. 죄송합니다!

(분명히 말하면 위의 내용은 출력 형식의 예일 뿐이며 항상 0보다 큰 숫자를 갖는 것은 아니며 프로필 제안이 2개 이상 있을 수 있습니다.)

답변1

sed다음 구성표를 사용할 수 있습니다 N;D.

sed -n 'N;s/PsA\( of Profile \([0-9]*\): \)[^0].*\nPsL\1[^0].*/\2/p;D'

다음 줄을 추가하므로 N패턴 공간에는 항상 두 줄이 있습니다. 그런 다음 동일한 프로필의 두 값과 0으로 시작하지 않는 숫자로 패턴을 정의하면 됩니다(따라서 앞에 0이 있는 값은 실패합니다!). 일치하는 항목이 있으면 패턴을 참조된 프로필 번호로 바꾸고 p인쇄합니다(옵션을 통해 기본 출력을 비활성화하는 동안 -n). 그런 다음 처음부터 시작하여 D두 줄이 있으면 이전 줄을 줄입니다.

이슈 업데이트에 따른 업데이트

귀하가 제공한 실제 시나리오에 대해서는 다른 접근 방식을 제안합니다.

sed -n '/Profile suggestion/!d;h;n;/(0/d;n;//d;g;p' yourfile

설명하다:

  • /Profile suggestion/!d의미: 프로필 제안 없이 모든 줄을 제거합니다. 다음 줄을 계속하려면 여기에서 스크립트를 중지하세요.
  • h필요한 경우 인쇄할 수 있도록 프로필 제안을 예약된 공간에 복사하세요.
  • n다음 줄로 계속 진행하세요. 명령 옵션으로 인해 -n현재 내용이 인쇄되지 않습니다.sed
  • /(0/d패턴을 찾으면 (0프로세스가 없다는 뜻이므로 이 루프를 제거하세요.
  • n;//d두 번째 줄에도 프로세스가 있는지 확인하려면 위와 정확히 동일합니다.
  • 스크립트의 이 시점에서 우리는 프릴프 제안이 있고 그 뒤에 각각 0이 아닌 프로세스 수가 있는 두 줄이 있다는 것을 알고 있습니다. 제안 사항을 인쇄 g할 수 있도록 예약된 공간을 패턴 공간으로 다시 복사하세요.p

답변2

awk -F": " '
    $0~/^PsA/ && $2 > 0 
    {
        getline; 
        if($2 <= 0) next; 
        sub(/[^0-9]*/, "", $1); 
        print $1
     }' data

PsA이것이 먼저 나온다고 가정하고 PsL다음 텍스트 줄( getline)을 잡고 값이 0보다 큰지 확인합니다.

성공하면 프로필 이름이 저장되었다는 사실이 악용 PsA되어 자체적으로 기록될 수 있습니다. PsL라인에서 가져 와서 인쇄하십시오.


귀하의 편집 내용에 따르면:

awk -F": " '
    $0~/^Profile/ && h=$0 {next} 
    $1~/^PsA/ && $2~/\([^0]/ {
        getline; 
        if ($2~/\([^0]/) print h
    }' data

현재 줄이 다음으로 시작하는 경우 Profile전체 헤더를 저장하고 다음 줄로 이동합니다.

대괄호 안의 첫 번째 필드가 PsA0이 아닌 경우 다음 행을 가져와 동일한 검사를 수행하고 성공하면 헤더를 인쇄합니다.

답변3

awk를 사용하세요:

참고: input.txt이는 테스트용 샘플 입력이 포함된 텍스트 파일입니다. comamnd의 출력을 이 awk 스크립트로 직접 파이프할 수 있습니다.

$ awk -F' +|\\(' '/^Profile/ {p=$0};
                  /^PsA/ {a=$5};
                  /^PsL/ {l=$5};
                  a > 0 && l > 0 && p {print p; p=""; a=0; l=0}' input.txt 
Profile suggestion (KDBGHeader): WinXPSP3x86
Profile suggestion (KDBGHeader): WinXPSP2x86

input.txt테스트용 샘플 입력이 포함된 텍스트 파일입니다. comamnd의 출력을 이 awk 스크립트로 직접 파이프할 수 있습니다.

이는 awk하나 이상의 공백을 사용하라는 의미입니다.또는왼쪽 대괄호는 필드 구분 기호 역할을 합니다. 이는 다섯 번째 필드 $5에 관련 프로세스 또는 모듈 수가 포함된다는 의미입니다.

awk 스크립트는 입력 파일을 읽고 "Profile"로 시작하는 줄의 경우 $0전체 줄( )을 변수에 캡처합니다 p.

"PsA" 또는 "PsL"로 시작하는 줄의 경우 각각 변수 a또는 l다섯 번째 필드( $5)에서 개수를 캡처합니다.

마지막으로 합계가 0 a보다 크고 비어 있지 않은 한 이전에 캡처한 프로필 라인을 인쇄 하고 변수 합계를 0과 빈 문자열 로 재설정합니다 .lppalp

또는 제안된 프로필 이름만 원하는 경우(프로필 줄의 다섯 번째 필드에도 있음):

$ awk -F' +|\\(' '/^Profile/ {p=$5};
                  /^PsA/ {a=$5};
                  /^PsL/ {l=$5};
                  a > 0 && l > 0 && p {print p; p=""; a=0; l=0}' input.txt 
WinXPSP3x86
WinXPSP2x86

관련 정보