Если sed
вас устраивает:
sed '/CLUSQMGR(/!d;s///;N;s/).*\n[^(]*(/ /;s/)$//'
Пояснение:
/CLUSQMGR(/!d
игнорирует все строки, не содержащие CLUSQMGR(
, на тот случай, если могут быть другие строки, которые вам не нужны s///
удаляет последний паттерн, которым являетсяCLUSQMGR(
N
добавляет следующую строку в пространство шаблонов со встроенным символом новой строки s/).*\n[^(]*(/ /
заменяет все от закрывающей скобки до первой открывающей скобки второй строки пробелом. Это делается путем привязки шаблона к символам новой строки(\n
)и [^(]*
, соответствующим любому количеству символов, кроме (
s/)$//
удаляет завершающий)
Для несжатых и сжатых файлов попробуйте:
for f in FILENAME_*; do
zcat -f "$f" | awk '/2020-04-20\|12345\|/ {rec=$2 "|" $3 "|" $4; a[rec]+=1}
END {for (rec in a) print FILENAME " : " rec " : " a[rec]}'
done > output.txt
Краткое пояснение:
*
). zcat -f <filename>
для распаковки входного файла (см. 1 , 2 ... )при необходимости на лету(-f
опция ). zcat -f <filename> | awk...
использует распакованный вывод файла $f
в качестве входных данных для awk
. 2020-04-20|12345|
увеличивайте массив ассоциативных счетчиков a
каждый раз, когда встречаете значение $2 | $3 | $4
в записи, проанализированной awk
. END
блока )и для каждого компонента rec
ассоциативного массива a
, конкатенация -напечатайте имя файла 'FILENAME', rec
значение $2 | $3 | $4
и количество вхождений этого значения a[rec]
. awk
делает доступными некоторые удобные внутренние переменные, такие как текущее обрабатываемое имя файла FILENAME. for
на output.txt
совершенно необязательно. Если вы подавите это, вы просто выведите на stdout
. ===================================
Этот ответ был ИЗМЕНЕН и улучшен на основе множества полезных комментариев @AdminBee, @roaima, @dave _thompson и @kusalananda.