问题: 编写bash脚本,我正尝试将csv文件中的产品列表导入数组:
#!/bin/bash
PRODUCTS=(`csvprintf -f "/home/test/data/input.csv" -x | grep "col2" | sed 's/<col2>//g' | sed 's/<\/col2>//g' | sed -n '1!p' | sed '$ d' | sed 's/ //g'`)
echo ${PRODUCTS[@]}
在交互式外壳中,结果/输出看起来很完美,如下所示:
burger
special fries
juice - 300ml
当我在bash脚本中使用完全相同的命令时,甚至在bash -x script.sh
的一部分中使用echo ${PRODUCTS[@]}
进行调试时,数组的结果是位于/ home / test的所有文件名/ data / 和:
burger
special
fries
juice
-
300ml
该数组正在接收目录列表并弄乱了换行符。在交互式外壳程序(单个命令行)中不会发生这种情况。 有谁知道该如何解决?
答案 0 :(得分:0)
查看csvprintf的文档,您正在将csv转换为XML,然后使用正则表达式进行解析。通常这是一个非常糟糕的主意。
您可能想安装csvkit,然后就可以安装
csvcut -c prod input.csv | sed 1d
或者您可以使用CSV解析器模块随附的语言。例如,红宝石
ruby -rcsv -e 'CSV.read("input.csv", :headers=>true).each {|row| puts row["prod"]}'
无论使用哪种方法,都应使用此结构将结果读入bash数组
mapfile -t products < <(command to extract the product data)
然后,打印数组元素:
for prod in "${products[@]}"; do echo "$prod"; done
# or
printf "%s\n" "${products[@]}"
围绕数组扩展的引号很关键。如果丢失,您将在每行看到一个单词。
提示:不要在外壳程序中使用ALLCAPS变量名:将那些变量名留给外壳程序。有一天,您将写PATH=something
,然后想知道为什么脚本损坏了。