Это легко сделать с помощью awk,
awk 'BEGIN{RS=""; FS="\n"; OFS=","; ORS="\n"}
{ for (i=1;i<=NF;++i) {c[FNR,i]=$i; sub(/^[[:blank:]]*/,"",c[FNR,i])} }
{ nf_max= (NF>nf_max?NF:nf_max) }
END{ for(j=1;j<=nf_max;++j) {
for(i=1;i<=FNR;++i) { printf ("%s" (i==FNR?ORS:OFS)), c[i,j] }
}
}' file
Это выведет CSV следующего формата:
ORG MANAGER,BILLING MANAGER,ORG AUDITOR
No ORG MANAGER found,No BILLING MANAGER found,xxx
,,yyy
,,zzz
,,aaa
,,bbb
,,ccc
Как это работает?
- Говоря awk, чтобы установить разделитель записей
RS
на пустую строку, мы определяем каждую запись как блок текста, разделенный пустой строкой.
- Каждое поле в этой записи разделено символом новой строки.
- Мы сохраняем каждое поле в массиве, который индексируется номером записи
FNR
и номером поля. Таким образом, мы можем полностью восстановить файл CSV.
- Поскольку вам нужен файл CSV, мы устанавливаем разделитель выходного поля
OFS
как символ , а разделитель выходной записи, который теперь является строками, - как символ .
- Мы отслеживаем максимальное количество полей в записи, которое указывает максимальное количество строк в файле CSV.
- Если у поля меньше максимального количества полей, мы все равно можем запросить содержимое этого поля из нашего массива, так как по умолчанию awk выводит строковые значения в пустое.
Ваш вопрос изначально задавался для файла CSV, но вы запросили файл TSV, который выровнен. Мы могли бы расширить вышеприведенную команду awk для этого, но было бы проще просто проанализировать полный вывод с помощью команды column
:
$ awk ... file | column -s, -o $'\t' -t
ORG MANAGER BILLING MANAGER ORG AUDITOR
No ORG MANAGER found No BILLING MANAGER found xxx
yyy
zzz
aaa
bbb
ccc
Вы можете использовать cat
, чтобы ожидать, что поля корректируются с пробелами, соответствующими ширине, и между полями вставляется только одна вкладка:
$ awk ... file | column -s, -o $'\t' -t | cat -vET
ORG MANAGER ^IBILLING MANAGER ^IORG AUDITOR$
No ORG MANAGER found^INo BILLING MANAGER found^Ixxx$
^I ^Iyyy$
^I ^Izzz$
^I ^Iaaa$
^I ^Ibbb$
^I ^Iccc$