gpt4 book ai didi

excel - 将 Bash 中的 CSV 读入字典/关联数组

转载 作者:行者123 更新时间:2023-12-04 00:53:31 25 4
gpt4 key购买 nike

我正在尝试将 csv 文件读入 bash 关联数组,但没有得到我期望的结果。

使用 Bash 5.0.18

Bellum:fox3-api rocky$ bash --version
GNU bash, version 5.0.18(1)-release (x86_64-apple-darwin19.5.0)

foobar.csv 的内容

Bellum:scripts rocky$ cat ./foobar.csv
foo-1,bar-1
foo-2,bar-2
foo-3,bar-3

problem.sh 的内容

#!/usr/bin/env bash

declare -A descriptions
while IFS=, read name title; do
echo "I got:$name|$title"
descriptions[$name]=$title
done < foobar.csv

echo ${descriptions["foo-1"]}
echo ${descriptions["foo-2"]}
echo ${descriptions["foo-3"]}

problem.sh 的实际输出

Bellum:scripts rocky$ ./problem.sh
I got:foo-1|bar-1
I got:foo-2|bar-2

bar-2

Bellum:scripts rocky$

期望的输出:

I got:foo-1|bar-1
I got:foo-2|bar-2
I got:foo-3|bar-3
bar-1
bar-2
bar-3

评论请求的输出

    Bellum:scripts rocky$ head -n 1 ./foobar.csv | hexdump -C
00000000 ef bb bf 66 6f 6f 2d 31 2c 62 61 72 2d 31 0d 0a |...foo-1,bar-1..|
00000010
    Bellum:scripts rocky$ od -c foobar.csv
0000000 357 273 277 f o o - 1 , b a r - 1 \r \n
0000020 f o o - 2 , b a r - 2 \r \n f o o
0000040 - 3 , b a r - 3
0000050

Cyrus 的 dos2unix 变化

    #!/usr/bin/env bash

declare -A descriptions
dos2unix < foobar.csv | while IFS=, read name title; do
echo "I got:$name|$title"
descriptions[$name]=$title
done

echo ${descriptions["foo-1"]}
echo ${descriptions["foo-2"]}
echo ${descriptions["foo-3"]}

Cyrus 的 dos2unix 更改的输出

    Bellum:scripts rocky$ ./problem.sh
I got:foo-1|bar-1
I got:foo-2|bar-2




Bellum:scripts rocky$

csv 文件是在 Mac 上通过从 Microsoft Excel 保存为 csv 来制作的。提前感谢您提供任何见解。

混合解决方案

对于 future 的人来说,这个问题实际上是两个问题。第一个是从 Microsoft Excel for Mac 工作簿中保存我的 CSV 文件。我另存为...“CSV UTF-8”格式(Excel 下拉菜单中列出的第一个 CSV 文件格式)。这增加了额外的字节,从而弄乱了 bash 中的读取命令。有趣的是,这些字节不会出现在 cat 命令中(请参阅原始帖子问题描述)。 将 CSV 从 Excel 中保存为“逗号分隔值”(位于格式下拉列表的下方),解决了第一个问题。

其次,@Léa Gris 和@glenn jackman 为我指出了正确的方向,即修改脚本有助于处理 Excel 保存文件中存在的一些换行符和回车符。 p>

谢谢大家。我花了一整天的时间试图弄清楚这一点。 经验教训:我应该早点转向 Stackoverflow。

最佳答案

这就是您没有得到预期输出的原因:

    Bellum:scripts rocky$ od -c foobar.csv
0000000 357 273 277 f o o - 1 , b a r - 1 \r \n
0000020 f o o - 2 , b a r - 2 \r \n f o o
0000040 - 3 , b a r - 3
0000050
  1. 第一行的名字不仅仅包含“foo-1”——还有额外的字符。
    • 可以使用 "${name#$'\357\273\277'}"
    • 删除它们
  2. 最后一行不以换行符结束,因此 while-read 循环只迭代两次。
    • read 如果无法读取整行,则返回非零值,即使它读取了某些字符。
    • 由于 read 返回“false”,while 循环结束。
    • 这可以通过以下方式解决:
      while IFS=, read -r name title || [[ -n $title ]]; do ... 
      #............................. ^^^^^^^^^^^^^^^^^^
    • 或者,只是修复文件。

结果:

BOM=$'\357\273\277'
CR=$'\r'

declare -A descriptions
while IFS=, read name title || [[ $title ]]; do
descriptions["${name#$BOM}"]=${title%$CR}
done < foobar.csv

declare -p descriptions
echo "${descriptions["foo-1"]}"
echo "${descriptions["foo-2"]}"
echo "${descriptions["foo-3"]}"
declare -A descriptions=([foo-1]="bar-1" [foo-2]="bar-2" [foo-3]="bar-3" )
bar-1
bar-2
bar-3

关于excel - 将 Bash 中的 CSV 读入字典/关联数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64518190/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com