PowerShell Select-String上下文不适用于从非PowerShell命令通过管道传递的输出

时间:2018-07-30 14:38:45

标签: powershell select-string

我正在尝试在PowerShell中使用Select-String来查看docker inspect命令的结果,但是Context属性似乎无法正常工作。

如您所知,docker inspect返回普通的JSON作为输出,例如:

[
    {
        "Id": "c8a5810c62d8dbea11335be561522b4a3df53b9ddcae5531ae06483926c5f992",
        "Created": "2018-07-31T17:16:53.8689464Z",
        "Path": "nginx",
        "Args": [
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 13613,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2018-07-31T17:16:54.6460418Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        ...
    },
    ...
]

运行slsSelect-String的别名)而没有任何其他参数:

enter image description here

并使用Context运行它:

enter image description here

如您所见,输出是相同的,并且我的输出中没有前后行

我可以使用grep做我想做的事;例如,

docker inspect devtest | grep Mounts -B 5 -A 5

grep的输出:

enter image description here

但是我想知道为什么Select-String不起作用。


更新

按照@iRon的建议,我什至尝试将输出保存到文件中,然后在文件(sample file)上使用Select-String

enter image description here

所以,我对所发生的事情感到非常困惑。因为对于@iRon来说,它工作正常。


更新2

我注意到,如果我做这样的事情:

$result = $json | Select-String "Mounts" -Context 5`

然后,当我查看$result[0].Context.PreContext(和PostContext)时,它们在输入中包含前和后行,但由于某些未知原因,它们没有打印到控制台上

1 个答案:

答案 0 :(得分:1)

如上所述,我没有安装Docker(就像我在Windows 10 Home上一样,但是我目前正在尝试安装Dock Toolbox)。
无论如何,我认为您应该可以通过拆分命令将docker从问题中排除:

$Json = docker inspect devtest
$Json | Select-String "Mounts" -Context 5

调查$Json字符串并建立一个MCVE问题,例如:
如何在原始文本文件上使用Select-String -Context

问题:

我有以下原始Json字符串:

$Json = @'
[
    {
        "Id": "c8a5810c62d8dbea11335be561522b4a3df53b9ddcae5531ae06483926c5f992",
        "Created": "2018-07-31T17:16:53.8689464Z",
        "Path": "nginx",
        "Args": [
            "-g",
            "daemon off;"
        ],
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/tmp/source/target",
                "Destination": "/app",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            }
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 13613,
            "ExitCode": 0,
            "Error": "",
        }
    }
]
'@

如果我运行$Json | Select-String "Mounts" -Context 5,则不会得到预期的结果。

答案

Select-String cmdlet需要行的流(数组),而不是的原始文本对象应由回车符和/或LineFeeds(或您的操作系统用于{{ 1}})。
这意味着一行(数组中的单个字符串项)甚至可以包含NewLine字符,但Select-String cmdlet仍将其视为单行
换句话说,Select-String cmdlet

NewLine的输出视为一行。

解决方案是将您的文本分成字符串(行)docker inspect devtest的数组:

String[]

结果:

$Json -Split "[\r\n]+" | Select-String "Mounts" -Context 5

您的test.json文件也可以正常运行:

  "Path": "nginx",
  "Args": [
  "-g",
  "daemon off;"
  ],
> "Mounts": [
  {
  "Type": "bind",
  "Source": "/tmp/source/target",
  "Destination": "/app",
  "Mode": "ro",