명령을 실행하고 해당 명령의 출력을 필터링한 다음 해당 출력 결과를 읽고 주어진 요구 사항을 충족하는 섹션만 인쇄하는 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 스크립트가 필요합니다.
나는 이 모든 것이 정말 처음이고 완전히 막혔습니다. 도와주세요!
** 편집 ** 명확성을 위해 Volatility Framework를 사용해 작업하려고 합니다. 얻을 수 있는 프로필을 보고 있는데 현재 정확한 출력은 다음과 같습니다.
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
테스트용 샘플 입력이 포함된 텍스트 파일입니다. 대신 명령의 출력을 이 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
테스트용 샘플 입력이 포함된 텍스트 파일입니다. 대신 명령의 출력을 이 awk 스크립트로 직접 파이프할 수 있습니다.
이는 awk
하나 이상의 공백을 사용하도록 지시합니다.또는필드 구분 기호로 여는 괄호(5번째 필드인 $5에 관련 프로세스 또는 모듈 수가 포함됨을 의미)
awk 스크립트는 입력 파일을 읽고 "Profile"로 시작하는 줄의 경우 전체 줄( $0
)을 변수에 캡처합니다 p
.
"PsA" 또는 "PsL"로 시작하는 줄의 경우 다섯 번째 필드( )에서 개수를 변수 a
또는 각각 캡처합니다 .l
$5
마지막으로 및 둘 다 0보다 크고 비어 있지 않을 때마다 a
이전 l
에 p
캡처한 프로필 줄을 인쇄 p
하고 변수를 0으로 설정 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