【问题标题】:UNIX shell script reading csvUNIX shell 脚本读取 csv
【发布时间】:2023-03-15 05:09:01
【问题描述】:

我有一个 csv 文件。我想将字段放入不同的变量中。假设 csv 文件的每一行包含三个字段。我有这个代码:

csvfile=test.csv
while read inline; do
   var1=`echo $inline | awk -F',' '{print $1}'`
   var2=`echo $inline | awk -F',' '{print $2}'`
   var3=`echo $inline | awk -F',' '{print $3}'`
   .
   .
   .
done < $csvfile

这段代码很好。但是,如果使用嵌入的逗号对字段进行编码,则它将不起作用。有什么建议吗?例如:

how,are,you
I,"am,  very",good
this,is,"a, line"

【问题讨论】:

  • 代码不好,它包含几个错误,不推荐使用的结构,并且是做你想做的事情的错误方法加上尝试将值保存在不同的变量中几乎可以肯定是反正是个坏主意。如果您发布简洁、可测试的示例输入和预期输出,我们可以为您提供帮助。
  • 听起来像 csvkit 这样的专用工具的工作;除此之外,你可以使用 gawk 和 FPAT: gnu.org/software/gawk/manual/gawk.html#Splitting-By-Content
  • 你想用你设置的vars 做什么?对于每一行,值都会发生变化,所以我认为你想在循环中对它们做一些事情。

标签: unix awk


【解决方案1】:

这可能不是完美的解决方案,但它适用于您的情况。

[cloudera@quickstart Documents]$ cat cd.csv 
a,b,c
d,"e,f",g

文件内容

csvfile=cd.csv
while read inline; do


var1=`echo $inline | awk -F'"' -v OFS='' '{ for (i=2; i<=NF; i+=2) gsub(",", "*", $i) }1' | awk -F',' '{print $1}' | sed 's/*/,/g'`
var2=`echo $inline | awk -F'"' -v OFS='' '{ for (i=2; i<=NF; i+=2) gsub(",", "*", $i) }1' | awk -F',' '{print $2}' | sed 's/*/,/g'`  
var3=`echo $inline | awk -F'"' -v OFS='' '{ for (i=2; i<=NF; i+=2) gsub(",", "*", $i) }1' | awk -F',' '{print $3}' | sed 's/*/,/g'`


echo  $var1 " " $var2 " " $var3 


done< $csvfile

输出:

[cloudera@quickstart Documents]$ sh a.sh 
a   b   c
d   e,f   g

所以基本上我们首先尝试处理数据中的“,”,然后用“*”替换“,”以使用 awk 获取所需的列,然后再次将 * 恢复为“,”以获取实际字段值

【讨论】:

  • 尝试此脚本时出现错误: awk:第 1 行附近的语法错误 awk:在第 1 行附近退出 awk:在第 1 行附近出现语法错误 awk:在第 1 行附近退出 awk:在第 1 行附近出现语法错误1 awk:在 1 号线附近救援
  • 有没有更有效的方法将字段放入变量中?在我实际的 csv 文件中,我每行有 15 个字段,并且有超过 8000 行。
  • 可以尝试存储 echo $inline | awk -F'"' -v OFS='' '{ for (i=2; i
  • 嗨,帕特,如果以上答案解决了您的问题,请您投票并将其标记为答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多