Сценарий оболочки 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()
возвращает количество выполненных замен).