简体   繁体   中英

Shell script to convert key-value pairs to CSV

I have got a file consisting of multiple key-value pairs and each entry for a set of key-value pairs is separated by a blank line. The file looks something like this:

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

And I want the following output from the code after processing the file:

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

I have tried using awk, but the arrangements of the keys are not consistent and as a result I do not get a desired output.

I need a Bash script that can give me the above mentioned output.

Store the values in an associative array (bash version 4 needed).

#!/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

Not a problem for 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()}
'

outputs

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM