в соответствии с более ранними ответами вы можете без проблем использовать UUID на любом «уровне» RAID, либо
С mawk
и gawk
, которые поддерживают регулярные выражения и многосимвольные -символьныеRS
(разделители записей):
awk -v RS='Gathering data' -F'\n' '/Drive name/ && !/Drive Speed/ && !/Drive Temp/{print$(NF-2)}' file
С awk
, который их не поддерживает, входные данные могут быть отфильтрованы, чтобы заменить их каким-либо одним символом, например формой -фид:
awk '/Gathering data/{$0="\f"} 1' file | awk -v RS='\f' -F'\n' '/Drive name/ && !/Drive Speed/ && !/Drive Temp/{print$(NF-2)}'
Если строки в записи не расположены в фиксированном порядке, целые записи могут быть напечатаны без {print...}
, а затем вывод может быть отфильтрован с помощью grep и т. д.
Этот подход имеет то преимущество, что условие согласования может быть изменено очевидным образом (, например. /Drive Speed: 7200 RPMs/
вместо !/foo/ && !/bar/
и т.д. ), что не загружает в память весь файл, а главное, не требует написания какого-то тупого конечного автомата.
Это Perl-версия:
#!/usr/bin/env bash
perl -ne '
$l = $_ if (/Drive name:/);
$s = 1 if (/Drive Speed:/);
if (/^\s*$/) {
print "$l\n" if (! defined($s));
$s = undef;
}
' "$1"
Предположим, что в конце входного файла есть пустая строка.
Запустить с :файлом test.sh
Всякий раз, когда в ваших данных есть пары тег/имя и значение, лучше всего создать/использовать массив, который имитирует это в вашем коде. Аналогично, если у вас есть блоки из нескольких -строковых записей. В вашем предыдущем вопросе я показал вам, как справиться с этим, когда ваши записи пусты -разделены строкой (см. https://unix.stackexchange.com/a/562552/133219), вот как это сделать, когда они не пусты, и как использовать более общий тег -val вместо того, чтобы полагаться на положение каждого значения в записи:
$ cat tst.awk
BEGIN { FS=": *" }
/^Gathering data/ { prt() }
{ tags2vals[$1] = $0 }
END { prt() }
function prt() {
if ( ("Drive name" in tags2vals) && ( !("Drive Speed" in tags2vals) || !("Drive Temp" in tags2vals) ) ) {
print tags2vals["Drive name"]
}
delete tags2vals
}
$ awk -f tst.awk file
Drive name: id1,sd@n5000cca8749
Drive name: id1,sd@n5000cca4607