简体   繁体   English

Bash,数组和空白导致奇怪的行为

[英]Strange behaviour with Bash, Arrays and empty spaces

Problem: Writing a bash script, i'm trying to import a list of products that are inside a csv file into an array: 问题:编写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[@]}

In the interactive shell, the result/output looks perfect as following: 在交互式外壳中,结果/输出看起来很完美,如下所示:

burger
special fries
juice - 300ml

When i use exactly the same commands in bash script, even debugging with bash -x script.sh , in the part of echo ${PRODUCTS[@]} , the result of array is all files names located at /home/test/data/ and: 当我在bash脚本中使用完全相同的命令时,即使使用bash -x script.sh调试,在echo ${PRODUCTS[@]} ,数组的结果是位于/ home / test / data的所有文件名/和:

burger
special
fries
juice
- 
300ml

The array is taking directory list AND messed up newlines. 该数组正在接收目录列表并弄乱了换行符。 This don't happen in interactive shell (single command line). 在交互式外壳程序(单个命令行)中不会发生这种情况。 Anyone know how to fix that? 有人知道该如何解决吗?

Looking at the docs for csvprintf , you're converting the csv into XML and then parsing it with regular expressions. 查看csvprintf的文档,您正在将csv转换为XML,然后使用正则表达式进行解析。 This is generally a very bad idea. 通常这是一个非常糟糕的主意。

You might want to install csvkit then you can do 您可能需要安装csvkit,然后才能执行

csvcut -c prod input.csv | sed 1d

Or you could use a language that comes with a CSV parser module. 或者,您可以使用CSV解析器模块随附的语言。 For example, ruby 例如,红宝石

ruby -rcsv -e 'CSV.read("input.csv", :headers=>true).each {|row| puts row["prod"]}'

Whichever method you use, read the results into a bash array with this construct 无论使用哪种方法,都可以使用此结构将结果读取到bash数组中

mapfile -t products < <(command to extract the product data)

Then, to print the array elements: 然后,打印数组元素:

for prod in "${products[@]}"; do echo "$prod"; done
# or
printf "%s\n" "${products[@]}"

The quotes around the array expansion are critical. 数组扩展周围的引号很关键。 If missing, you'll see one word per line. 如果丢失,您将在每行看到一个单词。


Tip: don't use ALLCAPS variable names in the shell: leave those for the shell. 提示:不要在外壳程序中使用ALLCAPS变量名:将变量名留给外壳程序。 One day you'll write PATH=something and then wonder why your script is broken. 有一天,您将编写PATH=something ,然后想知道为什么脚本损坏了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM