Вы можете использовать awk
, чтобы выполнить это:
awk -F"\t" '!$1{for(i=1;i<=NF;i++){line[i]=$i};next} {for(i=1;i<=NF;i++){printf i<NF?"%s%s%s":"%s%s%s\n",line[i],$i,FS}}' yourfile
Если вам нужен весь вывод, выровненный так, как у вас здесь (не с разделителями табуляции, а скорее как фиксированная ширина), вы можете передатьcolumn
awk -F"\t" '!$1{for(i=1;i<=NF;i++){line[i]=$i}} $1{for(i=1;i<=NF;i++){printf i<NF?"%s%s%s":"%s%s%s\n",line[i],$i,FS}}' test.log | column -t -s $'\t'
По сути, это то, что он делает:
- Разделение каждой строки на вкладке
-F"\t"
- Если первый столбец пуст, тособерите каждый столбец для этой строки в массив по номеру столбца в качестве индекса и перейдите к следующей записи
!$1{for(i=1;i<=NF;i++){line[i]=$i};next}
- Если мы все еще обрабатываем строку (это первое условие не сработало), то просмотрите каждыйстолбец
{for(i=1;i<=NF;i++)
- и распечатать, что хранится в массиве, содержимое столбца текущей строки, разделитель полей (вкладка) и перевод строки, если это последний столбец
{printf i<NF?"%s%s%s":"%s%s%s\n",line[i],$i,FS}}
Пример использования:
$ cat test.log
DISK OK - free space: CRITICAL
1/8/2018 7:05:05 Service Required Critical CPU:loadaverage 6%
1/8/2018 7:10:25 Service Alert Critical memoryUsage
:critical alert
DISK OK - free space:
2/8/2018 1:05:20 Service Alert Warning memoryUsage
:1.0,2.0,5.0
CRITICAl:outstanding alert attention
2/8/2018 2:05:20 Service Alert Critical required
$ awk -F"\t" '!$1{for(i=1;i<=NF;i++){line[i]=$i};next} {for(i=1;i<=NF;i++){printf i<NF?"%s%s%s":"%s%s%s\n",line[i],$i,FS}}' test.log | column -t -s $'\t'
1/8/2018 7:05:05 DISK OK - free space:Service Required Critical CRITICALCPU:loadaverage 6%
1/8/2018 7:10:25 Service Alert Critical memoryUsage
2/8/2018 1:05:20 DISK OK - free space:Service Alert Warning memoryUsage
2/8/2018 2:05:20 Service Alert Critical CRITICAl:outstanding alert attentionrequired