【问题标题】:Shell script to convert key-value pairs to CSV将键值对转换为 CSV 的 Shell 脚本
【发布时间】:2016-05-29 05:04:55
【问题描述】:

我有一个由多个键值对组成的文件,一组键值对的每个条目由一个空行分隔。该文件如下所示:

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 脚本。

【问题讨论】:

  • @AvihooMamka。嗯……不。您在上面发布的链接的可接受解决方案在这种情况下不起作用,因为每个组中的行顺序不固定。
  • @AvihooMamka 这是为了一致的数据。
  • 首先,尝试自己编写脚本,然后在此处发布有关脚本的问题。 stackoverflow.com/help/mcve

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


【解决方案1】:

对 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

【讨论】:

【解决方案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

【讨论】:

  • 注意关联数组仅在 bash 4+ 中可用
  • 谢谢@Choroba!!!该脚本正在运行,但是从值中删除了空格。
  • @Andy:抱歉,printf 中缺少双引号。现在应该修好了。
猜你喜欢
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 2013-12-02
  • 2020-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多