【问题标题】:Bash array from CSV and awk来自 CSV 和 awk 的 Bash 数组
【发布时间】:2016-02-05 16:56:13
【问题描述】:

我正在尝试使用以下命令在 BASH 中创建一个数组:

# Normally a loop, but for this example, n=1
arr=( `awk 'NR == n' n=1 "$file" | tr ',' " "` );
echo ${arr[@]};
echo ${arr[2]};

$file 包含:

"1","test_id = \"5\"","test_id <> \"5\""
"2","test_id = \"6\"","test_id <> \"6\""

输出:

"1" "test_id = \"5\"" "test_id <> \"5\""
"test_id

我希望${arr[2]} 的输出为test_id &lt;&gt; "5",但我实际上得到了"test_id

但是,当我像这样手动输入数据时,我得到了正确的结果:

arr=( "1" "test_id = \"5\"" "test_id <> \"5\"" );
echo ${arr[@]};
echo ${arr[2]};

输出:

1 test_id = "5" test_id <> "5"
test_id <> "5"

任何帮助将不胜感激,

谢谢。

【问题讨论】:

  • shell 会在空格处拆分——那些是您在替换逗号时添加的以及那些已经在字段中的。
  • 但这如何解释为什么第二个命令有效?它在字符串中包含空格。它不会被拆分。
  • 在第二种情况下,shell 正在解释引号。首先,它没有。这很棘手,但这就是麻烦。您还会注意到我没有引用修复;那是因为想出一个并不容易。事实上,鉴于您在数据中嵌套了双引号,并且其中一个字段中出现逗号只是时间问题,因此在 shell 中确实没有合适的方法来处理它。此时,您需要一个能够更稳健地处理 CSV 的工具。这可能是 Python、Perl 或自定义程序,例如 csvfix
  • 我还观察到您有一个非标准变体 CSV format。通常,字段内的双引号由"" 表示,而不是\"。这也会让人有些头疼。字段内的逗号和反斜杠会发生什么?我不认为您的变体很难处理,但由于它与默认值不匹配,您需要调整 Python 的 CSV 模块等工具才能正确处理它。只是一个提示。
  • 我明白了。感谢您的帮助!

标签: arrays bash shell csv awk


【解决方案1】:

正确答案当然在 cmets 中:使用真正的 CSV 解析器。话虽如此,这将是一种人为的解决方法:

. <(
      echo "arr=(";
      awk -F, 'NR==n && $1=$1' n=1 file
      echo ")"
)

获取此过程替换的结果会巧妙地改变报价解释阶段发生的顺序。它通常有助于解决这些复杂的问题。啊,为了摆脱不必要的tr 调用,awk 被指示以逗号分隔。 $1=$1 总是结果为真,并导致 awk 重新评估其行,因此输入字段分隔符更改为输出字段分隔符。

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 2013-05-19
    • 2011-05-02
    • 2019-04-11
    • 1970-01-01
    相关资源
    最近更新 更多