Разбор файла с помощью unix-команд

Ваш клиент должен сгенерировать свои собственные ключи и защитить их парольной фразой , а затем предоставить вам свой открытый ключ для хранения на сервере, которым вы управляете, и которым им необходимо получить доступ. Их закрытый ключ никогда и никому не должен передаваться, и он должен быть зашифрован (, то есть защищен парольной фразой ).

2
10.07.2020, 19:31
4 ответа

Вы можете использовать sedдля той же цели со следующим -вкладышем (, предполагая, что ваш файл называетсяfile):

sed -n 's/^.*LogType:\(stderr\)$/\1/p; s/^.*Log Upload Time :\(.*\)/\1/p; s/^.*LogLength:\(.*\)$/\1/p; s/^.*\(ERROR\|WARN\).*$/\0/p' file

Затем вы можете сохранить его вывод где-нибудь, используя перенаправление(>)в другой файл.

Разделение на несколько строк для облегчения чтения:

sed -n -e 's/^.*LogType:\(stderr\)$/\1/p' \
       -e 's/^.*Log Upload Time :\(.*\)/\1/p' \
       -e 's/^.*LogLength:\(.*\)$/\1/p' \
       -e 's/^.*\(ERROR\|WARN\).*$/\0/p' file

Обновление

Приведенное выше решение не исключает блоки, которые не относятся к «LogType :stderr», как запрошено OP; требуется не -локальная информация (не в той же строке ), которая не поддается обработке только с помощью sed.

Следующий сценарий, который использует как awk, так и sed, (с частью awk, вдохновленной этим постом ), выполняет эту работу:

#!/bin/bash
file=$1
awk '{
  if($0 ~ /LogType/){
    if(hold ~ /LogType:stderr/){
      print hold;
    }
    hold=$0
  }else{
    hold=hold "\n" $0
  }
}END{
  if(hold ~ /LogType:stderr/){
    print hold
  }
}' $file | sed -n -e 's/^.*LogType:\(stderr\)$/\1/p' \
                 -e 's/^.*Log Upload Time :\(.*\)/\1/p' \
                 -e 's/^.*LogLength:\(.*\)$/\1/p'       \
                 -e 's/^.*\(ERROR\|WARN\).*$/\0/p'
3
18.03.2021, 23:20

Я могу сделать это с помощью короткого скрипта. Оригинальный журнал содержится в файле logdata.

#!/bin/bash

tmpfile="/tmp/$0.$$"

sed -n '/stderr/,/^ *$/p' logdata > "$tmpfile"
sed -n 's/^.*LogType:\(.*\)/\1/p
        s/^.*Log Upload Time :\(.*\)/\1/p
        s/^.*LogLength:\(.*\)/\1/p' "$tmpfile"
grep -E "(ERROR|WARN)" "$tmpfile"
rm "$tmpfile"

Сначала мы извлекаем блок stderrво временный файл. Затем удалите два поля, а затем grepошибку и предупреждение. Я пытался соединить последние два шага, используя tee, но безуспешно.

Я мог бы сделать это без временного файла

sed -n '/stderr/,/^ *$/p' logdata | \
sed -n 's/^.*LogType:\(.*\)/\1/p
        s/^.*Log Upload Time :\(.*\)/\1/p
        s/^.*LogLength:\(.*\)/\1/p
        /ERROR/p
        /WARN/p'
1
18.03.2021, 23:20

Сawk:

awk '
  /LogType:stderr/ || (p && /Log( Upload Time|Length)/){
    p=1                    # set flag for stderr block
    sub(/^[^:]+:/, "")     # replace content before `:` including `:`
    print                  # print (modified) line
  }
  p && / (WARN|ERROR) /{ 
    sub(/^[^0-9]*/, "")    # remove unknown prefix
    print
  }  
  /LogType:stdout/{ exit } # exit the script
' file
1
18.03.2021, 23:20

Использование GNU sedи его расширенный режим регулярных выражений.

sed -Ee '
  /LogType:stderr/,/^\s*$/!d
  /Log Contents:/,/^\s*$/!{
    s/^[^:]*://;b
  }
  /\s(ERROR|WARN)\s/!d
' logfile

Пояснение:

  • Мы разбиваем файл на диапазон (тип журнала до пустой строки ), а затем подразделяем каждый диапазон на (предварительное содержимое журнала и сообщение)

  • В предварительном блоке поддиапазона уберите до первого символа двоеточия. Но пока не печатайте его, так как на данный момент мы не знаем, присутствует ли ошибка или предупреждение в пост-блоке поддиапазона. Так что держим его в трюмном пространстве.

  • Когда мы достигаем почтового блока в поддиапазоне, мы обнаруживаем строки ошибок или предупреждений. Затем извлеките удержание и распечатайте его сейчас.

Результаты:

stderr
Thu Jun 25 12:24:52 +0100 2020
3000
20/06/25 12:19:39 ERROR Exception found
20/06/25 12:20:41 WARN Warning as the node is accessed without started

Если вам нужны также номера строк сообщений об ошибках/предупреждениях, используйте приведенные ниже команды sed, которые изменены выше:

sed -Ee '
  /LogType:stderr/,/^\s*$/!d
  /Log Contents:/,/^\s*$/!{
    s/^[^:]*://;b
  }
  /\s(ERROR|WARN)\s/!d
  p;=;d
' logfile |
sed -Ee '/\s(ERROR|WARN)\s/N;s/\n/ on line #/'

Вы также можете использовать другие инструменты, такие как awk n perl, для выполнения этой работы :Примечание. :сначала удалите конечные пробелы из пустых строк.

awk '
  BEGIN {
    RS = "\n\n"              
    FS = "\nLog Contents:\n" 
    OFS = "\n"               
    ORS = OFS                
    spc = "[[:blank:]]" 
    str = "(ERROR|WARN)" 
    pat = spc str spc 
  }
  /^LogType:stderr/ &&
  NF == 2 {
    p = $1; gsub(/(^|\n)[^:]+:/, "\n", p);sub(/./, "", p) 
    N = split($2, a, /\n/)
    print p
    for ( i=1; i<=N; i++ ) 
      if ( a[i] ~ pat ) 
        print a[i]
  }
' logfile
perl -F'/^Log\hContents:$/m,$_,2' -00 -ne '
  next if ! /\ALogType:stderr$/m;
  (my $pre = $F[0])=~ s/.*?://gm;
  my $post = join "\n",
    grep { /\s(?:ERROR|WARN)/ }
    split /\n/, $F[1];
  print($pre,$post);
' logfile
1
18.03.2021, 23:20

Теги

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