循环遍历列

循环遍历列

我有一个 csv 文件,看起来像这样:

first_name,surname,email,
first_name2,surname2,email2,
....3,..
....4,...

每列的行数相同。

我想运行一个命令来迭代每一列并从每一列中获取值并将其替换到命令中。

例如,

for each_row;
 do [command foo{first_name} .... bar{surname}.... sth_else{email}]; 
done

我正在考虑做类似的事情

for i in `awk -F, '{print  $1}' my_file.csv`; do
  some command with i`;
done

但是,这仅允许我使用字段 1 中的值运行命令。我如何运行命令,以便它允许我在每次迭代时从每一列获取值?

答案1

假设您的 CSV 是“简单 CSV”格式,其中没有字段嵌入逗号或换行符(通用 CSV 文件中允许使用逗号或换行符,并正确引用字段),您可以直接使用以下命令读取字段read

while IFS=, read -r name familyname address; do
    printf 'Got "%s", "%s", and "%s"\n' "$name" "$familyname" "$address"
done <file.csv

read实用程序会将每一行拆分为 中的值的字段$IFS,并且我们确保在调用 时该变量包含逗号read。前两个逗号分隔字段将以变量name和结尾familyname,而该行的其余部分最终将出现在变量 中address。如果每行以不需要的逗号结尾(如问题中所示),则在每行读取一个虚拟变量(dummy在后面添加address作为单独的变量),或调整循环内的withread值以截掉尾随逗号。addressaddress=${address%,}

我们使用-rwithread来正确读取数据中的任何反斜杠。

如果 CSV 文件有需要跳过的标题行,

sed 1d file.csv |
while IFS=, read -r name familyname address; do
    printf 'Got "%s", "%s", and "%s"\n' "$name" "$familyname" "$address"
done

您可以使用代替sed命令(删除第一行输入并传递所有其他行),tail -n +2它可以执行相同的操作。

答案2

如果我理解正确,您可以使用xargs,例如:

$ cat file | sed 's/,$//' | xargs -d, -I {} echo {} | sed 's/a/@/'
first_n@me
sur n@me
em@il
first_n@me2
sur n@me2
em@il2

  • sed 's/,$//'将删除最后一个逗号,
  • xargs -d, -I {}: 将使用逗号-d,作为参数的分隔符,-I {}允许我们将参数传递给管道echosed

避免解析标头看看@他们的回答


注意:我稍微更改了输入,添加了空格。

答案3

awk可以像这样进行系统调用:

awk -F',' '{system("<command> "$1" "$2" "$3)}' file

可能需要引用传递给 shell 的变量,例如由两个空格分隔的元素组成的姓氏 - 这也取决于您的命令如何理解空格分隔的项目。在这种情况下使用:

awk -F',' '{system("<command> \""$1"\" \""$2"\" \""$3"\"")}'

相关内容