Выберите оставшийся текст в строке от файла журнала

Я использую оболочку Bash для обработки некоторых файлов журнала, которые я должен вставить файл CSV. Информацией, в которой я нуждаюсь, является дата начала процесса и время, дата окончания процесса и время, идентификатор Процесса и сообщение

Что я сделал, grep строки включая запущенный процесс и поместил их в файл, затем Grep закончил процессы и поместил их во второй файл. После того, как сделанный, я беру каждый файл и использую awk, чтобы разделить и извлечь необходимую информацию, вот мир кода, который я использую,

input=starts.txt
while IFS= read -r line
do
    procs=`echo $line | awk  '{ print $6;}' 
    date_s=`echo $line | awk '{ print $1;}'`
    time_s=`echo $line |  awk '{ print $2;}'`
    m1=`echo $line |  awk '{ print $3;}'`
    m2=`echo $line |  awk '{ print $4;}'`
    m3=`echo $line |  awk '{ print $5;}'`
    m4=`echo $line |  awk '{ print $7;}'`
    m5=`echo $line |  awk '{ print $8;}'`
    m6=`echo $line |  awk '{ print $9;}'`

 echo $procs ";" $date_s ";" $time_s ";" $m1 $m2  $m3 $m4 $m5 $m6 

one   < "$input" > result.csv

Строки имеют следующий формат:

02/01/2018 10:32:35      ANR4930I Reclamation process 1320 started for primary      storage pool VM_VTL_POOL automatically, threshold=75,     duration=None. (PROCESS: 1320) 

У меня есть две проблемы теперь:

  1. Цикл с условием продолжения не заканчивается.
  2. После извлечения времени/даты и идентификатора процесса, я хочу поместить остающееся сообщение в отдельное поле, не беря пословно и связывая их (m1 m2 m 3...) кроме того, если существуют какие-либо улучшения, которые могут быть сделаны к моему коду.
2
задан 1 July 2018 в 20:11

2 ответа

Я считал Вашу задачу как "перемещение поле 5 (process number) к передней стороне и затем выводу первые 3 поля, разделенные ;, сопровождаемый ; и затем остаток.

В Perl я сделал бы это как так (как острота):

perl -a -n -l -e \
    'unshift @F, splice(@F, 5, 1); 
     print join(";", @F[0..2]), ";@F[3..$#F]";' \
    < input.txt > output.csv

Результат:

input.txt:

02/01/2018 10:32:35      ANR4930I Reclamation process 1320 started for primary      storage pool VM_VTL_POOL automatically, threshold=75,     duration=None. (PROCESS: 1320) 
02/01/2018 10:32:35      ANR4930I Reclamation process 4567 started for primary      storage pool VM_VTL_POOL automatically, threshold=75,     duration=None. (PROCESS: 1320) 

output.csv:

1320;02/01/2018;10:32:35;ANR4930I Reclamation process started for primary storage pool VM_VTL_POOL automatically, threshold=75, duration=None. (PROCESS: 1320)
4567;02/01/2018;10:32:35;ANR4930I Reclamation process started for primary storage pool VM_VTL_POOL automatically, threshold=75, duration=None. (PROCESS: 1320)

Объяснение:

perl -a -n -l -e

  • разделите каждую входную строку в пробеле и поместите результат в предопределенный массив @F
  • обработайте каждую входную строку (но еще не печатайте ее),
  • используйте входной разделитель (\n) также как выходной разделитель (вполне упрощенный)
  • выполните следующее выражение для каждой входной строки

unshift @F, splice(@F, 5, 1);

  • удаляет 5-й элемент (count=1) из массива @F (который содержит одну строку Вашего входного разделения файла в пробеле), и предварительно ожидает тот 5-й элемент перед массивом @F.

print join(";", @F[0..2]), ";@F[3..$#F]";'

  • печатает первые 2 элемента @F с ; промежуток, затем
  • сопровождаемый литералом ; и затем остальная часть массива @F запуск в 3-м элементе в конец с пространством как разделитель. (print "@any_array" печатает объекты, разделенные пространством.)

Если Вы хотите тот же код как сценарий (сказать format-messages.pl), затем это выглядит немного отличающимся, потому что переключатели командной строки к Perl (которые теперь отсутствуют) implicitely добавляют некоторый код, который теперь должен быть добавлен explicitely. (Да, существуют другие пути, но...),

#!/usr/bin/env perl

use strict;
use warnings;

while(<>) {
    my @F = split;
    unshift @F, splice(@F, 5, 1); 
    print join(";", @F[0..2]), ";@F[3..$#F]\n";
}

Сделайте a chmod +x format-messages.pl и затем запущенный этот скрипт с ./format-messages.pl < input.txt > output.csv

4
ответ дан 1 July 2018 в 20:11

Самым большим улучшением будет полное отсутствие цикла оболочки и обработка каждой записи (строки) непосредственно в Awk. Например:

$ awk '{
    printf("%s;%s;%s;", $6, $1, $2)
    for(i=3; i<NF;i++) {
      if(i==6) continue; 
      printf("%s ", $i)
    }
    printf("%s\n",$NF)
  }' input
1320;02/01/2018;10:32:35;ANR4930I Reclamation process started for primary storage pool VM_VTL_POOL automatically, threshold=75, duration=None. (PROCESS: 1320)
5
ответ дан 1 July 2018 в 20:11

Другие вопросы по тегам:

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