Как очистить вывод, печатает желаемую информацию с меньшим использованием ЦП - PullRequest
0 голосов
/ 09 июля 2020

У меня есть файл журнала объемом 20 ГБ, в котором много полей, а номер поля или столбца 2 содержит числа. Я использую приведенные ниже команды для печати только столбца 2

zcat /path to file location/$date*/logfile_*.dat.zip | awk '/Read:ROP/' | nawk -F "=" '{print $2}' 

, результат этой команды:

"93711994166", Key

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

| awk -F, '{print $1}' | sed 's/"//g '

результат:

93711994166

моя конечная цель - печатать только числа, имеющие длину, отличную от 11 цифр, поэтому я добавляю следующее к моей последней команде:

 -vE '^.{11}$'

, поэтому моя последняя команда:

zcat /path to file location/$date*/logfile_*.dat.zip | awk '/Read:ROP/' | nawk -F "=" '{print $2}' | awk -F,  '{print $1}' | sed 's/"//g' | grep -vE '^.{11}$' >/tmp/$file

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

  • распечатать все числа длиной не равной 11 цифрам.
  • распечатать все числа, которые не начинаются с 93 (независимо от их длины)
  • чистая, эффективная команда, не требующая затрат на процессор или память

У меня есть еще одно требование, которое состоит в том, чтобы напечатать также числа, которые не начинались с 93.

Примечание:

файл журнала содержит много разных строк, но я использую awk '/Read:ROP/' для работы с приведенным ниже выводом и извлечения чисел

  Read:ROP (CustomerId="93700001865", Key=1, ActiveEndDate=2025-01-19 20:12:22, FirstCallDate=2018-01-08 12:30:30, IsFirstCallPassed=true, IsLocked=false, LTH={Data=["1|
    MOC|07.07.2020 09:18:58|48000.0|119||OnPeakAccountID|480|19250||", "1|RECHARGE|04.07.2020 10:18:32|-4500.0|0|0", "1|RECHARGE|04.07.2020 10:18:59|-4500.0|0|0"], Index=0
    }, LanguageID=2, LastKnownPeriod="Active", LastRechargeAmount=4500, LastRechargeDate=2020-07-04 10:18:59, VoucherRchFraudCounter=0, c_BlockPAYG=true, s_PackageKeyCount
    er=13, s_OfferId="xyz", OnPeakAccountID_FU={Balance=18850});

Ответы [ 2 ]

0 голосов
/ 09 июля 2020
sed '/.*Read:ROP.*([^=]="\([^"]*\)".*/!d; s//\1/'
  • /.../ - соответствие регулярному выражению
    • .*Read:ROP.* - соответствие Read:ROP, за которым следует что-либо с чем-либо впереди, ie. awk '/Read:ROP/'
    • ([^=]*=" - соответствует (, за которым следует что угодно, кроме =, затем =, затем ", ie. nawk -F "=" '{print $2}'
    • \([^"]*\) - сопоставить все внутри кавычек. Думаю, [0-9] тоже подойдет
    • ".* - удалить остаток строки
  • ! - если строка не соответствует регулярному выражению
    • d - удалить строку
  • s - заменить
    • // - повторно использовать регулярное выражение в /.../
    • \1 - заменяет первую обратную ссылку, ie. для \([^"]*\)
0 голосов
/ 09 июля 2020

Файл журнала 20 ГБ [...] zcat

Использование zcat для файлов журнала объемом 20 ГБ довольно дорого. Отметьте top при запуске вашей командной строки выше.

Возможно, стоит сохранить данные с первого шага фильтрации:

zcat /path to file location/$date*/logfile_*.dat.zip | awk '/Read:ROP/' > filter_data.out

и работать с отфильтрованными данные. Я предполагаю, что этот шаг awk может удалить большую часть данных.

Бонусные баллы: этот шаг можно распараллелить, запустив zcat [...] |awk [...] pipe файл за файлом, и вам нужно сделать это только один раз для каждого файла.

Остальные шаги не выглядят особенно дорогими, если даже после фильтрации не осталось много строк данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...