awk печатает 2 строки назад, если совпадает

Да, это [[:digit:]]~[0-9]~\d(, где ~означает приблизительно ).
В большинстве языков программирования (, где это поддерживается)

\d ≡ `[[:digit:]]`            # (is identical to, it is a short hand for).  

\dсуществует в меньшем количестве экземпляров, чем [[:digit:]](, доступный в grep -P, но не в POSIX ).

Цифры Юникода

В UNICODE много цифр , например:

123456789 # Hindu-ArabicАрабские цифры
٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI

Все из которых могут быть включены в [[:digit:]]или \d, и даже некоторые случаи [0-9].


POSIX

Для конкретных POSIX BRE или ERE:
\dне поддерживается (не в POSIX, а в GNUgrep -P). [[:digit:]]требуется POSIX для соответствия классу цифровых символов,который, в свою очередь, требует от ISO C символов от 0 до 9 и ничего больше. Так что только в локали C все [0-9], [0123456789], \dи [[:digit:]]означают абсолютно одно и то же. [0123456789]не имеет возможных неправильных интерпретаций, [[:digit:]]доступен в большем количестве утилит и в некоторых случаях означает только [0123456789]. \dподдерживается несколькими утилитами.

Что касается [0-9], значение выражений диапазона определяется только POSIX в локали C; в других локалях это может быть другим (может быть порядок кодовой точки или порядок сортировки или что-то еще ).

[0123456789]

Самый простой вариант для всех цифр ASCII.
Всегда действителен, (AFAICT )нет известных случаев сбоя.

Соответствует только английским цифрам:0123456789.

[0 -9]

Обычно считается, что [0-9]— это только цифры ASCII 0123456789.
В некоторых случаях это до боли неверно :Linux в какой-то локали, отличной от «C» (Июнь 2020 г. )Системы, например:

Предположим:

str='0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९'

Попробуйте grepобнаружить, что он позволяет большинство из них:

$ echo "$str" | grep -o '[0-9]\+'
0123456789
٠١٢٣٤٥٦٧٨
۰۱۲۳۴۵۶۷۸
߀߁߂߃߄߅߆߇߈
०१२३४५६७८

У этого сэда проблемы. Следует удалить только 0123456789, но удаляет почти все цифры. Это означает, что он принимает большинство цифр, но не некоторые девятки (???):

$ echo "$str" | sed 's/[0-9]\{1,\}//g'
 ٩ ۹ ߉ ९

То, что даже expr страдает теми же проблемами, что и sed:

expr "$str" : '\([0-9 ]*\)'             # also matching spaces.
0123456789 ٠١٢٣٤٥٦٧٨

А также ред

printf '%s\n' 's/[0-9]/x/g' '1,p' Q | ed -v <(echo "$str")
105
xxxxxxxxxx xxxxxxxxx٩ xxxxxxxxx۹ xxxxxxxxx߉ xxxxxxxxx९

[[ :цифра :]]

Существует множество языков :Perl, Java, Python, C. В которых[[:digit:]]\d)требуется расширенное значение. Например,этот perl-код будет соответствовать всем цифрам сверху:

$ str='0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९'

$ echo "$str" | perl -C -pe 's/[^\d]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९

Что эквивалентно выбору всех символов, имеющих свойства Unicode Numericи digits:

.

$ echo "$str" | perl -C -pe 's/[^\p{Nd}]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९

Какой grep может воспроизвести (конкретная версия pcre может иметь другой внутренний список числовых кодовых точек, чем Perl):

$ echo "$str" | grep -oP '\p{Nd}+'
0123456789
٠١٢٣٤٥٦٧٨٩
۰۱۲۳۴۵۶۷۸۹
߀߁߂߃߄߅߆߇߈߉
०१२३४५६७८९

снаряды

Некоторые реализации могут понимать диапазон как нечто отличное от простого порядка ASCII (ksh93, например)(при тестировании версии от мая 2018 г. (AT&T Research )93u+ 2012 -08 -01):

$ LC_ALL=en_US.utf8 ksh -c 'echo "${1//[0-9]}"' sh "$str"
  ۹ ߀߁߂߃߄߅߆߇߈߉ ९

Сейчас (июнь 2020 г. ), тот же пакет ksh93 из debian (та же версия sh (AT&T Research )93u+ 2012 -08 -01):

$ LC_ALL=en_US.utf8 ksh -c 'echo "${1//[0-9]}"' sh "$str"

 ٩ ۹ ߉ ९

И это кажется мне верным источником ошибок, ожидающих своего появления.

1
17.01.2020, 01:14
3 ответа
$ awk -F ':' '$1 == "Drive name" { saved = $0 } $0 == "failed to get drive stats" { print saved }' file
Drive name:  id1,sd@n5000cca8749
Drive name:  id1,sd@n5000cca4607

Это сначала устанавливает разделитель полей ввода равным :. Затем он сохраняет строку в переменной savedвсякий раз, когда обнаруживается строка, указывающая имя диска.

Если в строке указано failed to get drive stats, печатается текущее значение saved.

4
27.01.2020, 23:17

Вот почему в awk есть "режим абзаца", все, что вам нужно, это:

$ awk -v RS= -F'\n' '/failed to get drive stats/{print $2}' file
Drive name:  id1,sd@n5000cca8749
Drive name:  id1,sd@n5000cca4607
0
27.01.2020, 23:17

Пробовал использовать метод "Ниже", и он работал нормально

awk '{a[++i]=$0}/failed/{for(x=NR-2;x<NR;x++)print a[x]}' filename| sed -n '1~2p'

выход

Drive name:  id1,sd@n5000cca8749
Drive name:  id1,sd@n5000cca4607
0
27.01.2020, 23:17

Теги

Похожие вопросы