Разделить чередованную строку журнала на таблицу с помощью - PullRequest
0 голосов
/ 05 ноября 2019

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

"OUT 2019.11.05D04:51:39.583193000 ### hostname ### [blah] From 127.0.0.1 - Some Stuff here: ' Fred@somewhere.com, james@elsewhere.com, Steve@Cabbage.com, 75692, 45263, 99956, London, Sydney, Paris Some other Text ###"

Выше есть 3 элемента, которые я хочу превратить в строки, но я не знаю, сколько в нем будет реальных элементов. так может быть.

"OUT 2019.11.05D04:51:39.583193000 ### hostname ### [blah] From 127.0.0.1 - Some Stuff here: ' Fred@somewhere.com, james@elsewhere.com, Steve@Cabbage.com, Jane@doh.com, 75692, 45263, 99956, 22321, London, Sydney, Paris, Memphis Some other Text ###"

Выше есть 4 элемента, но это может быть любое число на самом деле примерно до 30

И я бы хотел превратить их в

Fred@somewhere.com  | 75692 | London
james@elsewhere.com | 45263 | Sydney
Steve@Cabbage.com   | 99956 | Paris
Jane@doh.com        | 99956 | Memphis

Обе стороны строки журнала всегда имеют одинаковый формат и количество слов, поэтому можно удалить первые 13 слов и последние 4. Число результирующих столбцов является статическим, 3 в последнем примере, но больше вреальный пример.

Мне нужна функция, которую я могу передать в хвост файла журнала и вывести результирующие строки

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

@ stephanmg Я дошел до этого:

#!/bin/bash
#

read INPUT
CLEAN_INPUT=`echo $INPUT |  cut -d" " -f16- | rev | cut -d" " -f5- | rev | sed 's/ //g'`

#echo $INPUT
#echo $CLEAN_INPUT
numCols=12

# i is affectively row number
# j is the column number i want
# NF/n is the number of rows
# so the field i want at any point is identified as i + (j-1)*NF/n
awk -F "," -v n=$numCols ' { for (i=1; i <= NF/n; i++) { for (j=1; j <= n; j++) { printf $(i+((j-1)*NF/n))"|" } ;print ""}} ' <<< $CLEAN_INPUT

, который работает, но заканчивается после одной строки при передаче по каналу к этому сценарию: - (

0 голосов
/ 05 ноября 2019

Новое решение:

#!/bin/bash

numCols=3
while IFS= read -r line
do
  CLEAN_INPUT=$(sed "s/.*'//; s/\([[:alpha:]]* \)\{3\}###$//" <<< $line)
  awk -F "," -v n=$numCols ' { for (i=1; i <= NF/n; i++) { print $(i),"|",$(i+NF/3),"|",$(i+2*NF/3) } }' <<< $CLEAN_INPUT
done < "input.txt

Редактировать: Это будет работать, только если INPUT - это одна строка:

#!/bin/bash

INPUT="OUT 2019.11.05D04:51:39.583193000 ### hostname ### [blah] From 127.0.0.1 - Some Stuff here: ' Fred@somewhere.com, james@elsewhere.com, Steve@Cabbage.com, 75692, 45263, 99956, London, Sydney, Paris Some other Text ###"
CLEAN_INPUT=$(sed "s/.*'//; s/\([[:alpha:]]* \)\{3\}###$//" <<< $INPUT)
numCols=3
awk -F "," -v n=$numCols ' { for (i=1; i <= NF/n; i++) { print $(i),"|",$(i+NF/3),"|",$(i+2*NF/3) } }' <<< $CLEAN_INPUT

Можете ли вы попробовать это?

Это дает желаемый результат:

Fred@somewhere.com |  75692 |  London
 james@elsewhere.com |  45263 |  Sydney
 Steve@Cabbage.com |  99956 |  Paris

Выравнивание вашей таблицы в текстовом формате, которое я оставляю в качестве упражнения для вас.

...