Скрипт 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

Я пытаюсь написать скрипт BASH, который будет считывать каждый раздел профиля по отдельности и выводить только те номера профилей, значения PsA и PsL которых больше 0.

Для ясности на выходе должно быть только значение профиля, поэтому в этом примере — 1, а 2 отброшено.

Это также должен быть скрипт BASH, учитывая работу, которую я пытаюсь выполнить.

Я совсем новичок во всем этом и совершенно застрял. Пожалуйста, помогите!

** EDIT ** Для ясности, я пытаюсь работать с 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следующую строку, поэтому в пространстве шаблона у вас всегда есть два. Затем вы просто определяете шаблон с обоими значениями одного и того же профиля и номером, который не начинается с нуля (поэтому значения с ведущими нулями не сработают!). Если есть совпадение, замените шаблон на указанный номер профиля и 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точно так же, как и выше, чтобы убедиться, что во второй строке также есть процессы
  • На этом этапе скрипта мы знаем, что у нас есть предложение prilfe с двумя следующими строками, каждая с ненулевым числом процессов. 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, будет содержать соответствующее количество процессов или модулей).

Скрипт awk считывает входной файл и для строк, начинающихся с «Profile», сохраняет всю строку ( $0) в переменную p.

Для строк, начинающихся с «PsA» или «PsL», он записывает количество в переменные aили, lсоответственно, из пятого поля ( $5).

Наконец, всякий раз, когда оба параметра aи lбольше 0 и 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

Связанный контент