Сценарий оболочки Bash: считать строки в каждом абзаце в файле на основе разделителя полей?

Я хочу проанализировать файл журнала, но застрял в этом случае:

Пример: у меня есть файл с таким форматом:

140508  0:00:19 10 abc  def
            9  djdj djdjd
            12 fjfj fjfjj                       
140508  0:00:24         10 dhdh dhdh
            19 dddh  hdhdhd
            1838 jcjj ddhfhfh
            17 fhfhh fhfhfh
140508  0:00:29         10 ababa cbcbc

Разделитель поля 140508 (ГГММДД).

Я хочу вывести количество строк в каждом абзаце на основе разделителя полей:

140508  0:00:19 3
140508  0:00:24 4
140508  0:00:29 1

Благодарю.

3 ответа

Использование awk:

awk '/^[0-9]{6} /{if (c) print a, b, c; a=$1; b=$2; c=1; next} {c++} END{print a, b, c}' file
140508 0:00:19 3
140508 0:00:24 4
140508 0:00:29 1

Используя awk

awk '/:/{h=$1 FS $2}{a[h]++}END{for (i in a) print i,a[i]}' file

объяснение

  • /:/{h=$1 FS $2}Работаю на линейке : только и сгенерируйте индекс массива a.
  • {a[h]++} Суммируйте время по этому индексу.
  • {for (i in a) print i,a[i]} пройти через массив и выполнить задание на печать.

Использование GNU awk:

awk --re-interval -v RS='(^|\n)[0-9]{6} ' \
 '$0=="" {sep=RT; next}  {print sep $1, 1+gsub("\n.",""); sep=substr(RT,2)}'  file

Примечание: если ваш gawk версия>> 4.0вам не нужно --re-interval вариант.

Объяснение:

  • Выражение даты [0-9]{6}  используется как разделитель записей (RS), который автоматически разбивает ввод на нужные абзацы; предшествуя этому с (^|\n) гарантирует, что сопоставление выполняется только в начале строк.
  • RT содержит буквальный терминатор записи, который соответствует RS регулярное выражение для записи под рукой; он сохраняется в sep переменная для обработки следующей записи.
    • Обратите внимание, что поскольку ввод начинается с разделителя записей, первая записанная запись пуста - следовательно, $0=="" образец и связанное действие.
    • Для всех последующих записей \n должен быть отрублен от сепаратора, который является то, что substr() звонок делает.
  • 1+gsub("\n.","") это маленькая хитрость, которая эффективно просто подсчитывает количество непустых строк в записи (gsub() возвращает количество выполненных замен).
Другие вопросы по тегам