awk: счетчик вхождений строки в одном столбце, между диапазоном линий, начинающих 2 строк ниже рисунка 1 и заканчивая условием

Данные присутствуют (по крайней мере, до 999 записей, всего не менее 6885 байтов пронумерованных бла):

> cat segfault.c 
int main(int argc, char *argv[])
{
    char *s = "hello world";
    *s = 'H';
}
> cc -g -o segfault segfault.c
> limit coredumpsize 9999999
> ./segfault `perl -le 'print "blah$_" for 1..999'`
Segmentation fault (core dumped)
> strings core.12231 | grep -c blah
1000

Затем с некоторое быстрое повторение gdb , и, если предположить символы отладки, это можно восстановить с помощью чего-то вроде:

> gdb ./segfault core.12231
...
(gdb) p argc
$1 = 1000
(gdb) x/1000s *argv
...

Другой вариант - использовать простую оболочку оболочки, которая регистрирует "$ @" где-то тогда exec s правильная программа с заданными аргументами.

3
09.01.2019, 20:22
3 ответа

ну наконец-то я разобрался со следующей строкой:

 awk '$1 ~ /m.o./ { n=NR+3}n && $3+0 > 0 { n=0 } {if ( n != 0 && $2 != "1" && $3+0 < 0) { count++; }} END { print count }' input

Проблема раньше заключалась в том, что каждое выражение, казалось, действовало на весь документ независимо, поэтому я не мог заставить условие работать только в пределах диапазона строк, что привело к подсчету многих других строк, которые я не учел. хотите, чтобы вас считали. Я продолжал получать значения больше, чем правильный ответ 3.

Например, при использовании флагов --, которые казались распространенным решением этой проблемы в сети --, казалось, что флаги не активировались в соответствующих строках, или подсчет происходил за пределами диапазона строк. разрешено флагами. Он считал линии, которые даже не были частью моего шаблона. В коде Inian исключались строки с шаблоном >>>> (, которые по какой-то причине возвращали совпадение счетчика ), но были и другие шаблоны, которые не совпадали, и было неразумно находить их все с 20 тыс. строк в документ.

Это то, что наконец сработало для меня.

 $1 ~ /m.o./ { n=NR+3}n

таким образом сценарий начинался с первого экземпляра, где $1 содержал «m.o.». Мне нужно было указать $1, чтобы избежать второго появления шаблона m.o. в сценарии. К счастью, второй экземпляр был за 2 доллара, поэтому я избежал его, сопоставив только за 1 доллар. Я не знаю, как этого избежать, если оба были в одном столбце.

В момент совпадения n определяется как номер строки (NR )плюс 3 в скобках, затем как-то записывается путем добавления его снова вне скобок. Таким образом, я, кажется, могу использовать awk, чтобы начать с шаблона плюс произвольное количество строк.

  && $3+0 > 0 {n=0}

Это позволяет мне заканчивать диапазон строк в соответствии с переменным условием, а не в соответствии с шаблоном (многие другие решения в Интернете сопоставляют определенный строковый шаблон, используя /pattern/ для определения конца диапазона строк, который Я не мог понять, как адаптировать здесь ).

Я полагаю, что && поддерживает сопоставление шаблона с предыдущим, чтобы связать начальную точку, а затем для любой последующей точки в документе, где $3 > 0 (мое условие ), n становится равным нулю.

Наконец, у меня есть способ связать начальную и конечную строки.

Теперь я могу применить желаемую функцию в пределах этого диапазона, а именно подсчет строк в соответствии с условием.

   {if ( n != 0 && $2 != "1" && $3+0 < 0) { count++; }}

Я остаюсь в пределах своего диапазона строк, вызывая первый член. :Если n не равно нулю, что имеет место только в случае совпадения моего шаблона и условий, которые я установил. В пределах этого диапазона строк сценарий извлекает строки, в которых $2 не равно 1, а $3 является отрицательным. Это увеличивает мою переменную count на 1 для каждого экземпляра.

   END { print count }' input

В конце скрипта выводится суммарное количество переменных для моего входного файла.

1
27.01.2020, 21:29

Есть много способов сделать это, но самый простой для понимания может быть следующим:

Вы можете создать сложное условие для выбора строк для подсчета:

awk 'BEGIN { total=0 } NR > 3 && $2 != 1 && $3 < 0  { total++ } END { print total }' 

Или вы можете поместить условное выражение внутри блока кода:

awk 'BEGIN { total=0 } NR > 3 { if ( $2 != 1 && $3 < 0 ) { total++ } } END { print total }' 
0
27.01.2020, 21:29

Вы можете попробовать этот awk:

awk '$1=="m.o."{if(l){exit};l++;next}l&&l<3{l++;next}l{if($3<0&&$2!=1)c++}END{print c}' infile
0
27.01.2020, 21:29

Теги

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