Это нелегко, потому что трудно определить, когда у вас есть разные стили строки - те, у которых есть значения как в столбце 1, так и в столбце 2, те, у которых нет значения в столбце 1 и в столбце 2, и в столбце 1 или 2 значения нет. Первый шаг - сделать это проще - sed
на помощь:
$ sed 's/[[:space:]]\{1,\}$//
s/^....../&|/
s/|....../&|/
:a
s/|\( *[0-9][0-9]* \)\( *[^|]\)/|\1|\2/
t a' data
1 | 1000 | 0 | 100 | 10 | 200 | 20 | 300 | 30 | 400
| | 40 | 500 | 50 | 600 | 60 | 700 | 70 | 800
| 1010 | 0 | 101 | 10 | 201 | 20 | 301 | 30 | 401
| | 40 | 501 | 50 | 601
2 | 1000 | 0 | 110 | 15 | 210 | 25 | 310 | 35 | 410
| | 45 | 510 | 55 | 610 | 65 | 710
| 1010 | 0 | 150 | 10 | 250 | 20 | 350 | 30 | 450
| | 40 | 550
$
Первая строка удаляет все пробелы, чтобы избежать путаницы. Следующие два выражения обрабатывают столбцы фиксированной ширины 1 и 2 (по 6 символов в каждом). Следующая строка создает метку a
; заменитель находит трубу |
, несколько пробелов, несколько цифр, пробел и некоторый конечный материал, который не содержит трубы; и вставляет трубу посередине. t a
возвращается к метке, если была сделана замена.
С этим становится легко управлять awk
с разделителем полей |
.
Это многословно, но, кажется, делает свое дело:
awk -F '|' '
$1 > 0 { printf "%5d %4d %3d %3d\n", $1, $2, $3, $4
for (i = 5; i <= NF; i += 2) { printf "%5s %4s %3d %3d\n", "", "", $i, $(i+1) }
next
}
$2 > 0 { printf "%5s %4d %3d %3d\n", "", $2, $3, $4
for (i = 5; i <= NF; i += 2) { printf "%5s %4s %3d %3d\n", "", "", $i, $(i+1) }
next
}
{ for (i = 3; i <= NF; i += 2) { printf "%5s %4s %3d %3d\n", "", "", $i, $(i+1) }
next
}'
Выход:
1 1000 0 100
10 200
20 300
30 400
40 500
50 600
60 700
70 800
1010 0 101
10 201
20 301
30 401
40 501
50 601
2 1000 0 110
15 210
25 310
35 410
45 510
55 610
65 710
1010 0 150
10 250
20 350
30 450
40 550
Если вам нужно удалить заголовки, добавьте 1d;
в начало сценария sed
.