【问题标题】:Read a csv file from a bash scripting file从 bash 脚本文件中读取 csv 文件
【发布时间】:2019-08-03 13:43:31
【问题描述】:

在一个文件夹中,我有 2 个文件。 Valuation.csv 和另一个文件 myScript.sh

我的 CSV 文件有 10 行和 5 列。我曾多次尝试阅读它,但它从未奏效。这是我在 myScript.sh 中尝试的代码:

第一次尝试:

#!/bin/bash

    while read -r line do
        field1=$(echo $line | awk -F'|' '{printf "%s", $1}' | tr -d '"')
        field2=$(echo $line | awk -F'|' '{printf "%s", $2}' | tr -d '"')

        echo $field1 $field2 done < $Valuation.csv

结果:/myScript.sh:第 10 行:.csv:没有这样的文件或目录

第二次尝试:

cat Valuation.csv|while read line   do
read -d, col1 col2 < <(echo $line)
echo "I got:$col1|$col2"   done

结果:什么都没有

我正在运行这样的文件:

./myScript.sh

谢谢

Here the csv file opened with excel

【问题讨论】:

  • 为什么不使用通用脚本语言,例如 python/perl?
  • 嗨@James,你能提供一个文件的内容吗?
  • 将 Excel 工作表另存为 .csv 并将数据作为文本发布,而不是电子表格的图片。 Bash 无法读取电子表格的图片。
  • @James :变量 Valuation 为空/未定义。除此之外,我认为以这种方式处理 CSV 不是一个好主意,因为它仅适用于相当简单的 CSV 文件。例如,如果其中一个字段包含(引用的)| 作为值,则 awk 部分不起作用。

标签: linux bash csv terminal


【解决方案1】:

这是我的文件 data.csv

Site,Post,Subject,User,Status
stackover flow,bash,read csv,James,ok
git,linux,core,Novy,ko

在我的 bash 脚本中,我有类似的内容:

#!/bin/bash
INPUT=./data.csv
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read site post subject usr status
do
    echo "Site : $site"
    echo "Post : $post"
    echo "Subject : $subject"
    echo "User : $usr"
    echo "Status : $status"
done < $INPUT
IFS=$OLDIFS

输出

网站:stackover 流程 帖子:重击 主题:读取 csv 用户:詹姆斯 状态:好的 站点:git 发表: linux 主题:核心 用户:诺维 状态:ko

你可以给看看here

【讨论】:

  • 谢谢,你能给我看一张你的文件的照片吗?是“站点、帖子、主题、用户、状态”列吗?
  • csv 文件是带有逗号或分号分隔符的文本文件。文件内容在文章的开头。复制它并在本地创建您的 csv 文件。我希望清楚重要的是“在阅读站点帖子主题 usr 状态”之后,您可以使用带有“$”加变量名的变量
【解决方案2】:

James,请避免在 bash 的循环中调用实用程序。这是非常低效的。避免使用固定数量的字段——如果添加另一个字段怎么办?只需使用 read -a array... 并将 内部字段分隔符 设置为以逗号分隔的单词(例如 IFS=$',\n'),您就可以相当轻松地在 bash 中读取 .csv 数据。

例如,编写一个将.csv 文件名作为第一个参数读取的脚本,您可以这样做:

#!/bin/bash

declare -i row=0

while IFS=$',\n' read -r -a array; do
    printf "row %d - read %d fields.\n" $((row++)) ${#array[@]}
    for i in "${array[@]}"; do
        printf " %-12s" "$i"
    done
    echo ""
done < "$1"

(注意:虽然您在实践中希望在 awk 中处理整个问题,因为这似乎是一个 bash 练习,简而言之 .csv 文件,bash 不仅仅是有能力)

示例数据

(我不打算重新输入您的电子表格,所以这里是前两行)

$ cat company.csv
Facebook,35587,55800000000,1567988,491000000000,8.80x
Uber,16000,11300000000,706250,120000000000,10.6x

运行脚本并简单地输出行数和每行字段,然后是字段值本身,您会得到:

$ bash readcsv.sh company.csv
row 0 - read 6 fields.
 Facebook     35587        55800000000  1567988      491000000000 8.80x
row 1 - read 6 fields.
 Uber         16000        11300000000  706250       120000000000 10.6x

检查一下,如果您有任何问题,请告诉我。

【讨论】:

  • 感谢大卫的回答。我实现了第一个脚本,它正在工作,但格式完全关闭。谢谢,但是,我真的不明白您稍后编写的示例数据的目的是什么。我是否需要有一行代码带有“$ cat Valuation.csv?我应该在 myScrip.sh 文件中实现它吗?
  • 您可以更改printf 语句的格式——我只是使用左对齐的 12 个字符 field-width 来确保字段之间的均匀分隔。无需cat validation。显示数据的目的是因为您发布了您的数据的图片,而不是您的实际数据。大多数人会因为这个原因而忽略你的问题——他们不会重新输入你的数据。我以.csv 格式重新输入了两行。您只需提供filename.csv 作为脚本的第一个参数。 (如果需要,您可以添加读取以使用标题行)
猜你喜欢
  • 2020-06-18
  • 2014-10-26
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 2014-04-13
  • 2012-09-28
  • 1970-01-01
相关资源
最近更新 更多