在列数未知的表格右侧添加一列

问题描述 投票:0回答:1

我有两个表(一个是1.csv,另一个是2.csv)。第一个由名称和分数组成,例如...

name,score
Alice,6
Bob,1
Joe,2
John,7
Michel,9

另一个有一个表,其列数不固定(有时只有一列,有时是两列,有时是三列..),就像......

Alice, Bob,
Michel,
Joe,John

我想在姓名字段右侧添加一个新的分数列来分配他/她的分数。 所以,期望的结果是,

Alice,6,Bob,1
Michel,9
Joe,2,John,7

如何实施?我更喜欢使用 awk/bash 脚本来完成此任务。预先感谢,

我尝试运行以下脚本,

#!/bin/bash

declare -A scores
while IFS=',' read -r name score
do
    scores["$name"]=$score
done < 1.csv

while IFS=',' read -r -a names
do
    for name in "${names[@]}"
    do
        name=$(echo "$name" | xargs)
        echo -n "$name,${scores[$name]},"
    done
    echo
done < 2.csv

我期待这样的结果,

Alice,6,Bob,1
Michel,9
Joe,2,John,7

在这个 MWE 案例中似乎没问题,但对于更大的表,它不再起作用。 我应该如何改进?

linux bash awk datatable
1个回答
0
投票

如果您想使用 bash 和强制 POSIX 工具(即没有 python、perl、ruby 等)来执行此操作,那么 bash 部分只需调用单个 awk 脚本来完成其余操作,请参阅 whats-the-most -robust-way-to-efficiently-parse-csv-using-awk 了解一般如何使用 awk 解析 CSV,但根据您提供的示例输入,使用任何 POSIX awk,以下内容可能足以满足您的需求:

$ cat tst.sh
#!/usr/bin/env bash

awk '
    BEGIN { FS = OFS = "," }
    {
        sub(/\r$/,"")
        for ( i=1; i<=NF; i++ ) {
            gsub(/[[:space:]]+/," ",$i)
            gsub(/^ | $/,"",$i)
        }
    }
    NR == FNR {
        if ( NR > 1 ) {
            name2score[$1] = $2
        }
        next
    }
    {
        sub(FS"$","")
        for ( i=1; i<=NF; i++ ) {
            printf "%s%s%d%s", $i, OFS, name2score[$i]+0, (i<NF ? OFS : ORS)
        }
    }
' 1.csv 2.csv

$ ./tst.sh
Alice,6,Bob,1
Michel,9
Joe,2,John,7
© www.soinside.com 2019 - 2024. All rights reserved.