%20%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85%20%D0%B2%20%D0%BE%D0%B4%D0%B8%D0%BD%20%D1%81%D1%82%D0%BE%D0%BB%D0%B1%D0%B5%D1%86%2C%20%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%B2%20%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BA%D0%B8%20%D1%81%D1%82%D1%80%D0%BE%D0%BA..png)
У меня есть отчеты, которые создаются в следующем формате с разделителями-табуляциями:
UNIT TC CC PC TCP FTX FRX
HOUSE 55 65 75 85 95 105
CAR 100 200 300 400 500 600
H2 5 10 15 20 25 30
C2 10 20 30 40 50 60
Мне нужно изменить их на следующий формат:
HOUSE TC 55
HOUSE CC 65
HOUSE PC 75
HOUSE TCP 85
HOUSE FTX 95
HOUSE FRX 105
CAR TC 100
CAR CC 200
CAR PC 300
CAR TCP 400
CAR FTX 500
CAR FRX 600
И так далее.
Я хотел бы использовать стандартные инструменты, такие как SED AWK BASH, но любые предложения приветствуются. Код будет вставлен в скрипт BASH, который я уже использую для анализа и объединения данных заранее. Количество записей всегда будет одинаковым, отчеты не изменятся.
решение1
Пытаться:
$ awk 'BEGIN { FS="\t" } NR==1 { split($0,header,"\t") ; next } { for(i=2;i<=NF;i++) print $1,header[i],$i }' data
HOUSE TC 55
HOUSE CC 65
HOUSE PC 75
HOUSE TCP 85
HOUSE FTX 95
HOUSE FRX 105
CAR TC 100
CAR CC 200
CAR PC 300
CAR TCP 400
CAR FTX 500
CAR FRX 600
H2 TC 5
H2 CC 10
H2 PC 15
H2 TCP 20
H2 FTX 25
H2 FRX 30
C2 TC 10
C2 CC 20
C2 PC 30
C2 TCP 40
C2 FTX 50
C2 FRX 60
Однострочник, разбитый на части:
Установите символ табуляции в качестве разделителя полей входных файлов:
BEGIN { FS="\t" }
Если первая строка ( NR==1
) разбивает ее на поля и сохраняет их в массиве header
. Это проще, чем копировать все поля $1, $2, ... в цикле for и сохранять их. Команда next
также предотвращает обработку строки 1 следующим кодом, который предназначен только для других строк. ( FS
вместо "\t"
было бы более последовательно...)
NR==1 { split($0,header,"\t") ; next }
Для каждой другой строки ( NR!=1
) выведите все поля ( $2...$NF
) с префиксом $1 и именем поля ( header[i]
).
{ for(i=2;i<=NF;i++) print $1,header[i],$i }
Настройка OFS=FS="\t"
в BEGIN
блоке заставит print
использовать табуляцию между полями. Я не изменил это в ответе, потому что для этого также нужно будет переформатировать все выходные строки.