用于将键值对转换为CSV的Shell脚本

时间:2016-02-17 13:08:12

标签: bash shell csv export-to-csv keyvaluepair

我有一个由多个键值对组成的文件,一组键值对的每个条目都用空行分隔。该文件看起来像这样:

Name = Jhon
Age = 27
Street = LA Road
Occupation = Service
Gender = M

Name = Anindya
Gender = M
Street = GNB Road
Occupation = Consultant
Age = 26
Phone = 0987654321

Age = 55
Gender = F
Street = Jodhpur Road
Name = Gopa

Gender = M
Name = Ashok
Occupation = Service
Phone = 1234567890

我想在处理文件后从代码输出以下内容:

Name,Age,Gender,Street,Occupation,Phone
Jhon,27,M,LA Road,Service,
Anindya,26,M,GNB Road,Consultant,0987654321
Gopa,55,F,Jodhpur Park,,
Ashok,,M,,Service,1234567890

我尝试过使用awk,但是键的排列并不一致,因此我没有获得所需的输出。

我需要一个可以提供上述输出的Bash脚本。

2 个答案:

答案 0 :(得分:2)

将值存储在关联数组中(需要bash版本4)。

#!/bin/bash
set -eu

columns=(Name Age Gender Street Occupation Phone)

declare -A record header
for c in "${columns[@]}" ; do
    record[$c]=$c
    header[$c]=1
done

output () {
    for ((i=0; i<${#columns[@]}; i++ )) ; do
        k=${columns[i]}
        printf %s "${record[$k]:-}"
        if (( i+1 != ${#columns[@]} )) ; then
            printf ,
        fi
    done
    echo
}

# Print the header.
output
record=()

while read key eq value ; do
    if [[ ! $key ]] ; then
        output
        record=()

    elif [[ $eq != = ]] ; then
        echo Invalid line "$key $eq $value" >&2
        exit 1

    elif [[ ! ${header[$key]:-} ]] ; then
        echo Invalid key "'$key'" >&2
        exit 1

    else 
        record[$key]=$value
    fi
done

# Don't forget the last line!
output

答案 1 :(得分:0)

awk不是问题:

awk -F " = " -v OFS="," '
    BEGIN { print "Name", "Age", "Gender", "Street", "Occupation", "Phone" }
    function printline() {
        print data["Name"], data["Age"], data["Gender"], data["Street"], data["Occupation"], data["Phone"]
    }
    {data[$1] = $2}
    NF == 0 {printline(); delete data}
    END {printline()}
'

输出

Name,Age,Gender,Street,Occupation,Phone
Jhon,27,M,LA,Service,
Anindya,26,M,GNB,Consultant,0987654321
Gopa,55,F,Jodhpur Road,,
Ashok,,M,,Service,1234567890