명령을 실행하고 해당 명령의 출력을 필터링한 다음 해당 출력의 결과를 읽고 주어진 요구 사항을 충족하는 부분만 인쇄하는 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
전체 헤더를 저장하고 다음 줄로 이동합니다.
대괄호 안의 첫 번째 필드가 PsA
0이 아닌 경우 다음 행을 가져와 동일한 검사를 수행하고 성공하면 헤더를 인쇄합니다.
답변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과 빈 문자열 로 재설정합니다 .l
p
p
a
l
p
또는 제안된 프로필 이름만 원하는 경우(프로필 줄의 다섯 번째 필드에도 있음):
$ 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