【问题标题】:Using $ variables in jq from PowerShell在 PowerShell 的 jq 中使用 $ 变量
【发布时间】:2018-01-16 16:30:10
【问题描述】:

我正在使用此代码:

jq --raw-output "(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv" output2.json > output3.csv

从我的 JSON 数据库创建 CSV:

[
  {
    "key1": "field1",
    "key2": "field2",
    "key3": "field3"
  },
  {
    "key1": "field4",
    "key2": "field5",
    "key3": "field6"
  }
]

https://jqplay.org/ 的输出非常完美,但在我的命令行上运行时似乎根本不起作用。 我在 VSCode 中使用 PowerShell。

我不断收到此错误。

jq:错误:语法错误,意外的'|',期待'$'或'['或'{'(Windows cmd shell引用问题?)在, 第 1 行: (map(keys) | add | unique) as |地图(。作为 | | 地图([.]))作为 | , [] | @csv jq: 1 编译错误

我猜想$ 是问题所在,因为它们没有显示在错误文本中,所以我尝试以各种方式转义它们,但没有任何进展。 我进行了广泛的搜索,似乎没有人有这个问题,所以我一定是得到了一些非常简单非常错误的东西。

【问题讨论】:

  • 您是将整行作为字符串传递,还是按原样传递?您需要将其作为字符串传递并转义 |人物。您还需要注意powershell语法:$表示在cmd窗口中执行命令。

标签: json powershell jq


【解决方案1】:

您的jq 脚本:

  • 必须作为 文字 PowerShell 字符串 ('...')
  • 传递
  • 因为一个插值 PowerShell 字符串("...")在设计上将$-前缀标记解释为PowerShell 变量引用;例如,$cols(或 PowerShell 子表达式 ($(...)),在这种情况下不适用):
jq -r '(map(keys) | add | unique) as $cols | 
       map(. as $row | $cols | map($row[.])) as $rows | 
         $cols, $rows[] | @csv' output2.json > output3.csv

* 为了便于阅读,我添加了换行符。 PowerShell 字符串文字可以跨越多行,因此您应该能够按原样粘贴多行命令。当然,您可以将其格式化为单行。
* -r 确保结果是“原始”输出,即没有 JSON 值转义。
* 如果您将jq 脚本保存到文件 以与-f 选项一起使用,请确保将其保存为UTF-8 不带BOM


下面是一个演示差异的简化示例:

# OK: SINGLE-quoted jq script:
PS> '{ "foo": "bar" }' | jq '. as $cols | .foo'
"bar"

# BROKEN: DOUBLE-quoted jq script: PowerShell expands `$cols` up front, 
#         resulting in an empty string, if no such PowerShell variable exists. 
#         jq then effectively sees '. as  | .foo', which explains the syntax error.
PS> '{ "foo": "bar" }' | jq ". as $cols | .foo"
jq: error: syntax error, unexpected '|', expecting '$' or '[' or '{' (Unix shell quoting issues?) at <top-level>, line 1:
. as  | .foo      
jq: 1 compile error

【讨论】:

  • 已解决。另一个问题的问题是编码。 jq 需要没有 BOM 的 UTF-8。其他任何事情都会引发错误。标记为已解决。谢谢!
【解决方案2】:

作为参考,当我将您的(略微格式化的)过滤器放入名为 filter.jq 的文件中时

  (map(keys) | add | unique) as $cols
| map(. as $row | $cols | map($row[.])) as $rows
| $cols, $rows[]
| @csv

你的数据在一个名为json.data的文件中并运行

jq -r -f filter.jq json.data

我看到以下输出

"key1","key2","key3"
"field1","field2","field3"
"field4","field5","field6"

所以问题很可能出在您正在运行的确切命令中。没有看到很难说,但是将过滤器放在单独的文件中可能会防止任何命令行引用/转义问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 2023-03-09
    • 1970-01-01
    • 2017-09-08
    • 2018-10-11
    • 2012-09-05
    相关资源
    最近更新 更多