使用 shell 脚本将另一个字段上的函数结果附加到 csv 中,awk

Appending result of function on another field into csv using shell script, awk

我有一个 csv 文件作为临时变量存储在 shell 脚本 (*.sh) 中。

假设数据如下所示:

Account,Symbol,Price
100,AAPL US,200
102,SPY US,500

我想添加第四列 "Type",它是 shell 函数 "foobar" 的结果。 运行 来自命令行或 shell 脚本本身:

$ foobar "AAPL US"
"Stock"
$ foobar "SPY US"
"ETF"

如何将此列添加到我的 csv 中,并通过调用将第二列作为参数的 foobar 来填充它?澄清一下,这是我的理想结果 post-script:

Account,Symbol,Price,Type
100,AAPL US,200,Common Stock
102,SPY US,500,ETF

我在网上看到很多例子涉及使用 awk 添加这样的列,并用固定值、条件值、其他列的数学推导等填充新列 - 但没有在另一个字段上调用函数和存储它的输出。

awk 救援!

$ echo "Account,Symbol,Price
100,AAPL US,200
102,SPY US,500" | 
awk -F, 'NR>1{cmd="foobar "; cmd | getline type} {print [=10=] FS (NR==1?"Type":type)}'

不确定是否需要引用 foobar

的输入

您可以使用这个 awk:

export -f foobar

awk 'BEGIN{FS=OFS=","} NR==1{print [=10=], "Type"; next} {
   cmd = "foobar \""  "\""; cmd | getline line; close(cmd); 
   print [=10=], line
}' file.csv

Account,Symbol,Price,Type
100,AAPL US,200,Common Stock
102,SPY US,500,ETF

不使用awk的另一种方式:

paste -d, input.csv <({ read; printf "Type\n"; while IFS=, read -r _ s _; do foobar "$s"; done; } < input.csv)

@anubhavas 的回答是一个很好的方法,所以请不要更改已接受的答案,因为我只是将其作为答案发布,因为它太大并且需要格式化以适合评论。

FWIW 我会把他的 awk 脚本写成:

awk '
    BEGIN { FS=OFS="," }
    NR==1 { type = "Type" }
    NR > 1 {
        cmd  = "foobar 7"  "7"
        type = ((cmd | getline line) > 0 ? line : "ERROR")
        close(cmd)
    }
    { print [=10=], type }
' file.csv

至:

  1. 更好地保护 $2 免受 shell 扩展,并且
  2. 防止静默打印先前的值 if/when cmd | getline 失败,并且
  3. 将打印语句合并为 1 行,以便轻松更改所有输出行 if/when 必要