Транспонировать 1-ю и 3-ю строку из файла CSV в столбцы в скриптах оболочки - PullRequest
1 голос
/ 11 ноября 2019

Мне нужно транспонировать 1-ю и 3-ю строку из файла CSV и добавить несколько ключевых слов. Например, у меня есть файл, который содержит такие данные.

Col1,Col2,Col3,Col4,Col5,Col6
AA,AA,AA,AA,AA,AA
String,String,Bigint,Int,String,"Decimal(15,2)"

Я попытался транспонировать 1-ю и 3-ю строку, и мой вывод выглядит следующим образом

Col1,String,Col2,String,Col3,Bigint,Col4,Int,Col5,String

Это код, который я имеюнаписано.

hadoop fs -text $f | sed -n '1p;3p' | awk -F, '{for (i=1; i<=NF; i++) a[i,NR=$i; max=(max<NF?NF:max)} END {for (i=1; i<=max; i++) {for (j=1; j<=NR;j++) printf "%s%s" , a[i,j], (i==NR?RS:FS) }}'

Это то, чего я хочу достичь.

CAST(Col1 AS String) AS Col1,
CAST(Col2 AS String) AS Col2,
CAST(Col3 AS Bigint) AS Col3,
CAST(Col4 AS Int) AS Col4,
CAST(Col5 AS String) AS Col5,
CAST(Col6 AS Decimal(35,2)) AS Col6

1 Ответ

3 голосов
/ 11 ноября 2019

От данного образца к ожидаемому результату, используя GNU awk (если используется FPAT, а не FS):

$ awk '
BEGIN {
    # FS=","                        # no quoted fields
    FPAT="([^,]*)|(\"[^\"]+\")"
}
NR==1 {
    for(i=1;i<=NF;i++)
        a[i]=$i
}
NR==3 {
    for(i=1;i<=NF;i++) {
        gsub(/^"|"$/,"",$i)
        printf "CAST(%s AS %s) AS %s%s\n",a[i],$i,a[i],(i==NF?"":",")
    }
    exit
}' file

Выход:

CAST(Col1 AS String) AS Col1,
CAST(Col2 AS String) AS Col2,
CAST(Col3 AS Bigint) AS Col3,
CAST(Col4 AS Int) AS Col4,
CAST(Col5 AS String) AS Col5

Однострочник для вашегосантехника:

$ ... | awk 'BEGIN{FPAT="([^,]*)|(\"[^\"]+\")"}NR==1{for(i=1;i<=NF;i++)a[i]=$i}NR==3{for(i=1;i<=NF;i++){gsub(/^"|"$/,"",$i);printf "CAST(%s AS %s) AS %s%s\n",a[i],$i,a[i],(i==NF?"":",")}exit}'

Обновлен вывод с полями в кавычках:

CAST(Col1 AS String) AS Col1,
CAST(Col2 AS String) AS Col2,
CAST(Col3 AS Bigint) AS Col3,
CAST(Col4 AS Int) AS Col4,
CAST(Col5 AS String) AS Col5,
CAST(Col6 AS Decimal (35,2)) AS Col6

Обновление Версия для FPAT меньше awks. Он имеет парсер начального уровня для работы с запятыми в (одной паре) двойных кавычек (\" не обрабатывается правильно):

awk '
function parse(str,    i,j,n,q) {
    for(i=1;i<=length(str);i++) {
        if(i==length(str)||(substr(str,i+1,1)=="," && q==0)) {
            b[++n]=substr(str,j+1,i-j)
            j=i+1
        }
        if(substr(str,i+1,1)=="\"")
            q=(!q)
    }
    return n
}
BEGIN {
    FS=","
}
NR==1 {
    for(i=1;i<=NF;i++)
        a[i]=$i
}
NR==3 {
    n=parse($0)
    for(i=1;i<=n;i++) {
        gsub(/^"|"$/,"",b[i])
        printf "CAST(%s AS %s) AS %s%s\n",a[i],b[i],a[i],(i==n?"":",")
    }
    exit
}' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...