BASH - 如何从 CSV 文件中的列中提取数据并将其放入数组中?
Posted
技术标签:
【中文标题】BASH - 如何从 CSV 文件中的列中提取数据并将其放入数组中?【英文标题】:BASH - How to extract data from a column in CSV file and put it in an array? 【发布时间】:2013-09-11 06:16:03 【问题描述】:我正在学习在 Bash 中编写脚本。
我有一个 5 列 22 行的 CSV 文件。我有兴趣从第二列中获取数据并将其放入数组中。
我想要的是第一个名字在array[0]
,第二个在array[1]
等等。
Bash 脚本:
#!/bin/sh
IFS=","
eCollection=( $(cut -d ',' -f2 MyAssignment.csv ) )
printf "%s\n" "$eCollection[0]"
CSV 看起来像这样。没有带标题的行。
带有Vl18xx
数字的列是我要拆分为数组的列。
John,Vl1805,VRFname,10.9.48.64/28,10.9.48.78
John,Vl1806,VRFname,10.9.48.80/28,10.9.48.94
John,Vl1807,VRFname,10.9.48.96/28,10.9.48.110
John,Vl1808,VRFname,10.9.48.112/28,10.9.48.126
John,Vl1809,VRFname,167.107.152.32/28,167.107.152.46
bash 脚本没有将第二列放入数组中,我做错了什么?
【问题讨论】:
删除您的 IFS 分配。 【参考方案1】:删除IFS=","
分配,从而让空格、制表符、换行符的默认 IFS 值应用
#!/bin/bash
eCollection=( $(cut -d ',' -f2 MyAssignment.csv ) )
printf "%s\n" "$eCollection[0]"
解释:eCollection
变量是一个数组,由于外括号。它使用来自$(cut -d ',' -f2 MyAssignment.csv)
子shell 的IFS 分隔(想想函数或命令行参数)单词中的每个元素进行初始化,这是cut
命令与','
分隔符一起使用并打印第二个字段@987654327 @来自MyAssignment.csv
文件。
printf
语句仅显示如何按索引打印任何项目,您也可以尝试echo "$eCollection[@]"
查看所有元素。
【讨论】:
如果存在空格,这个答案会遇到麻烦,即:纽约 如果 CSV 包含带逗号的引用字段,这不会中断吗? 是的,字段中的空格会是个问题。但问题中的数据不包含空格。我正在寻找最简单的方法。 我知道这个答案解决了这个问题,以及为什么它有这么多赞成但它缺乏对语法的正确解释,这使得初学者很难从中学习。【参考方案2】:我喜欢使用awk
。首先根据,
分隔符拆分,并将所需的列值放入数组中。
abc=($(tail -n +1 MyAssignment.csv | awk -F ',' 'print $2;'))
echo $abc[1]
索引从 1 开始。如果文件包含标题,请将 +1
替换为 +2
以忽略标题。
【讨论】:
【参考方案3】:两种纯 bash 解决方案:
eCollection=()
while IFS=',' read -r _ second _; do
eCollection+=("$second")
done < file.txt
printf '%s\n' "$eCollection[0]"
readarray -t eCollection < file.txt
eCollection=("$eCollection[@]#*,")
eCollection=("$eCollection[@]%%,*")
printf '%s\n' "$eCollection[0]"
【讨论】:
谢谢 Aleks,我也会尝试您提出的解决方案。【参考方案4】:最好使用readarray
。无需介意 IFS 可能有任何价值,并且不受路径名扩展的影响。
readarray -t eCollection < <(cut -d, -f2 MyAssignment.csv)
printf '%s\n' "$eCollection[0]"
【讨论】:
最后 IFS 让我很难受,因为我的列中包含带有空格的数据。然后我尝试了你提出的方法,它就像一个魅力!谢谢大佬!以上是关于BASH - 如何从 CSV 文件中的列中提取数据并将其放入数组中?的主要内容,如果未能解决你的问题,请参考以下文章
当我将 pandas 数据框保存为 csv 文件时,从 18 位长的列中截断 3 位