преобразовать CSV-файл с помощью скрипта awk - PullRequest
0 голосов
/ 08 октября 2019

У меня есть CSV-файл, как показано ниже:

C1, C2,   C3,Cv1,Cv2,Cv3,Cv4 ...  this one can be have longer column
x1, x2 ,x3.1, 1.1, 1.2, 1.3, 1.4
x1, x2, x3.2, 2.1, 2.2, 2.3, 2.4
x1, x2, x3.3, 3.1, 3.2, 3.3, 3.4

Я хотел бы преобразовать этот CSV-файл, как показано ниже:

C1,C2,   C3,CTEXT,XVALUE
x1, x2, x3.1, Cv1 , 1.1
x1, x2, x3.1, Cv2 , 1.2
x1, x2, x3.1, Cv3 , 1.3
x1, x2, x3.1, Cv4 , 1.4
x1, x2, x3.2, Cv1 , 2.1
x1, x2, x3.2, Cv2 , 2.2
x1, x2, x3.2, Cv3 , 2.3
x1, x2, x3.2, Cv4 , 2.4
x1, x2, x3.3, Cv1 , 3.1
x1,x2,x3.3, Cv2 , 3.2
x1,x2,x3.3, Cv3 , 3.3
x1,x2,x3.3, Cv4 , 3.4

Ниже мой код:

#!/bin/bash
awk -F, -v OFS=, '{ if (NR==1)
{ print $1,$2,$3, "CTEXT","XVALUE"
  i=4; while (i < NF) {
   a[i]=$i; i=i+1
  }
  am=NF; next
}
i=4 ; while (i < am) {
  if (i > NF) {print "record "NR" insufficient value" >/dev/stderr
  break}
  print $1,$2,$3,a[i],$i
  i=i+1
  }
if (am <NF) print "record "NR" too many values for text" >/dev/stderr
}' input.csv

Когда я запускаю скрипт, он показывает ошибку:

awk: синтаксическая ошибка рядом со строкой 2 awk: выход из строя рядом со строкой 2


Редактировать Эд Мортон - я простозапускал скрипт через beautifier (gawk -o- '...'), так что его было легче читать / понимать:

{
    if (NR == 1) {
        print $1, $2, $3, "CTEXT", "XVALUE"
        i = 4
        while (i < NF) {
            a[i] = $i
            i = i + 1
        }
        am = NF
        next
    }
    i = 4
    while (i < am) {
        if (i > NF) {
            print("record " NR " insufficient value") > (/dev/) stderr
            break
        }
        print $1, $2, $3, a[i], $i
        i = i + 1
    }
    if (am < NF) {
        print("record " NR " too many values for text") > (/dev/) stderr
    }
}

Ответы [ 2 ]

2 голосов
/ 08 октября 2019

Даже если вы переключите свой Solaris awk на gawk или nawk, некоторые проблемы все равно останутся. Не могли бы вы попробовать следующее:

awk -F, -v OFS=, '
NR==1 {
    print $1,$2,$3, "CTEXT","XVALUE"
    for (i = 4; i <= NF; i++) a[i]=$i
    am=NF; next
}
{
    if (am < NF) {
        print "record "NR" too many values for text" > "/dev/stderr"
        next
    }
    for (i = 4; i <= am; i++) {
        if (i > NF) {
            print "record "NR" insufficient value" > "/dev/stderr"
            break
        }
        print $1,$2,$3,a[i],$i
    }
}' input.csv
  • Вам нужно увеличить i до NR или am (не <но <=). </li>
  • Заключить/dev/stderr с кавычками.
  • Лучше использовать цикл for, чем while.

Надеюсь, это поможет.

0 голосов
/ 08 октября 2019

как то так

$ awk -F, 'BEGIN {OFS=FS} 
           NR==1 {n=split($0,h); 
                  print $1,$2,$3,"CTEXT","XVALUE"; 
                  next} 
           n!=NF {print n<NF?"too many":"not enough"; 
                  exit} 
                 {for(i=4;i<=NF;i++) print $1,$2,$3,h[i],$i}' file

C1,C2,C3,CTEXT,XVALUE
x1,x2,x3.1,Cv1,1.1
x1,x2,x3.1,Cv2,1.2
x1,x2,x3.1,Cv3,1.3
x1,x2,x3.1,Cv4,1.4
x1,x2,x3.2,Cv1,2.1
x1,x2,x3.2,Cv2,2.2
x1,x2,x3.2,Cv3,2.3
x1,x2,x3.2,Cv4,2.4
x1,x2,x3.3,Cv1,3.1
x1,x2,x3.3,Cv2,3.2
x1,x2,x3.3,Cv3,3.3
x1,x2,x3.3,Cv4,3.4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...