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, получите следующую строку и выполните ту же проверку, в случае успеха напечатайте заголовок.
Вы можете использовать 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
точно так же, как и выше, чтобы убедиться, что во второй строке тоже есть процессы g
копирует пробел обратно в пространство шаблона, поэтому мы можем p
напечатать предложение Использование 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