bash 循环遍历 csv
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9725175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Looping through csv
提问by user983223
I'm writing a bash shell script and I'm having trouble splitting stdout csv and then looping over it.
我正在编写一个 bash shell 脚本,但在拆分 stdout csv 然后对其进行循环时遇到了问题。
I get data from stdout of a database. It is comma delimited and each row is on its own line. I store that in a variable called csv. I have the same thing for my data variable. I get that data from stdout from a url which returns csv...again it is comma delimited and each row has its own line.
我从数据库的标准输出中获取数据。它以逗号分隔,每一行都在自己的行上。我将它存储在一个名为 csv 的变量中。我的数据变量也有同样的事情。我从返回 csv 的 url 的 stdout 中获取数据...同样,它是逗号分隔的,每一行都有自己的行。
Below \n means it is a new line.
\n 下方表示它是一个新行。
I know how to iterate through and get any of the columns for csv using the read (see below). So when I echo out $col1 it displays two results which is what I expect.
我知道如何使用 read 迭代并获取 csv 的任何列(见下文)。因此,当我回显 $col1 时,它会显示两个结果,这正是我所期望的。
This is what I don't understand: I then want to get for each of $col1 I want to see if $col1 equals any of the data of the first column of the $data variable. If it exists (it should always exist unless there was an issue) then prepend $col1 of csv onto all the data of the data variable to add that data to form a stdout csv.
这是我不明白的:然后我想为每个 $col1 获取我想查看 $col1 是否等于 $data 变量第一列的任何数据。如果它存在(除非出现问题,否则它应该始终存在)然后将 csv 的 $col1 预先添加到数据变量的所有数据上以添加该数据以形成标准输出 csv。
csv=$("csv",123\n"csv2",456)
data=$("data1",123\n"data2",456)
echo "$csv" | while IFS=',' read -r col1 col2;do
echo "$col1"
done
example of what is needed:
需要什么的例子:
if $csv[$col1] == [any of the values of $data[$col1]] then;
echo $csv[$col1],$data[all of it]
回答by David W.
I'm going to reformat your data as:
我要将您的数据重新格式化为:
DATA
数据
Col #1 Col #2
===== ====
data1 123
data2 456
CSV
CSV文件
Col #1 Col #2
==== ====
csv 123
csv2 456
Do I have this setup correctly? I know these will be CSV files, but I want to make sure I understand your data structure.
我的设置正确吗?我知道这些将是 CSV 文件,但我想确保我了解您的数据结构。
Now you said:
现在你说:
I [...] want to get for each of $col1 I want to see if $col1 equals any of the data of the first column of the $data variable.
我 [...] 想要获取每个 $col1 我想看看 $col1 是否等于 $data 变量第一列的任何数据。
You want to match column #1 from DATAwith column #1 from CSV. In your set, the two column #1 from both sets don't match. Did you mean Column #2?
您想将DATA 中的第 #1 列与CSV 中的第 #1列进行匹配。在您的集合中,两组中的两列 #1 不匹配。您是说第 2 列吗?
I am assuming that your final results should look like this:
我假设你的最终结果应该是这样的:
DATA
数据
CVS Value Col #1 Col #2
========= ====== ======
csv data1 123
csv2 data2 456
(but in csv format, of course).
(但当然是 csv 格式)。
Is this correct?
这样对吗?
If you have a fairly modern version of BASH, you can use associative arrays. This allows you to have the concept of a keyequaling a value.
如果您拥有相当现代的 BASH 版本,则可以使用关联数组。这允许您拥有键等于值的概念。
Let's say you create an associate array out of both DATA and CSV where the array is keyed by column #2, you could then go through an array, and determine if there's a matching value, and outputting the data the way you want.
假设您从 DATA 和 CSV 中创建了一个关联数组,其中该数组由第 2 列作为键,然后您可以遍历一个数组,确定是否存在匹配值,并以您想要的方式输出数据。
You can set an associative array value by this:
您可以通过以下方式设置关联数组值:
my_array[key]="value"
You can get the value associated with key like this:
您可以像这样获取与键关联的值:
echo "${my_array[key]}"
You can get a list of all values like this:
您可以获得所有值的列表,如下所示:
echo "${my_array[*]}"
You can get all keys like this:
您可以像这样获得所有密钥:
echo "${my_array[@]}"
Here's a quick and dirty program. You probably want something to verify that you don't have duplicate keys when you create your array, and that a particular key has a value associate with it when you print your array:
这是一个快速而肮脏的程序。您可能想要一些东西来验证您在创建数组时没有重复的键,并且在打印数组时特定键具有与其关联的值:
#! /bin/bash
csv="csv,123
csv2,456"
data="data1,123
data2,456"
# Create the Data Array Hash keyed by Col #2
while IFS="," read -r col1 col2
do
data_array[$col2]=$col1
done <<EOD
$data
EOD
# Create the CSV Array Hash keyed by Col #2
while IFS="," read -r col1 col2
do
csv_array[$col2]=$col1
done <<EOD
$csv
EOD
#For each key in Data Hash, print out corresponding keyed value in CSV Hash
for key in "${!data_array[@]}"
do
echo "$key: ${data_array[$key]} ${csv_array[$key]}"
done

