【问题标题】:Powershell if foreach(Powershell 如果 foreach(
【发布时间】:2017-04-09 04:54:00
【问题描述】:

我必须在一个相当大的文件中找到所有内容超过 4 个的行 ;

例如这个文件

Text1;Text2;Text3;Text4;Text5;
Text1;Text2;Text3;Text4;Text5;
Text1;Text2;Text3;Text4;Text5;
Text1;Text2;Text3;Text4;Text5;
Text1;Text2;Text3
Text1;Text2;Text3;Text4;Text5;
Text1;Text2;Text3
Text1;Text2;Text3;Text4;Text5;

数行数没问题

$content=Get-Content .\sample.txt
[regex]::matches($content,";").count

给了我 34 次点击。

计算每行所需的字符也没问题

$content=Get-Content .\sample.txt
foreach ($lines in $content) {[regex]::matches($lines,";").count}

给予

  • 5
  • 5
  • 5
  • 5
  • 2
  • 5
  • 2
  • 5

现在我想获得少于 4 条的所有行;

我试过了:

if (foreach ($lines in $content) {[regex]::matches($lines,";").count} -le 3) {Write-Host $lines}

但这给了我一个错误。

有了这个

$count=foreach ($lines in $content) {[regex]::matches($lines,";").count}
if ($count -le 3) {Write-Host $lines}

我得到了一条线 - 最后的匹配线,但没有另一条线。

foreach和if如何结合?

【问题讨论】:

  • Get-Content .\sample.txt | ? {[regex]::matches($_,";").count -le 3}

标签: powershell if-statement foreach


【解决方案1】:

这段代码的语法有误:

if (foreach ($lines in $content) {[regex]::matches($lines,";").count} -le 3) {Write-Host $lines}

您不要将foreach 放在if 语句的条件括号内。在foreach 中使用if 语句,而不是像这样:

$content=Get-Content .\sample.txt
foreach ($lines in $content) {
    $semiCols = [regex]::matches($lines,";").count
    if($semiCols -le 3) {
        Write-Host $semiCols
    }
}

输出

PS E:\Programming\PowerShell> .\lines-fetch.ps1
2
2
PS E:\Programming\PowerShell>

【讨论】:

  • 好吧,您可以将语句放在需要表达式的地方,方法是将其包装在 $(...)
  • @Joey 我不太喜欢 PoweShell 脚本,但正如您所说,该语句必须包含在 $(...) 中,OP 在他的示例中没有使用它。再次,请参阅 OP 在此处提供的这个特定示例。如果你将foreach 语句包装在$(...) 中,你会得到什么?这是if ($(foreach ($lines in $content) {[regex]::matches($lines,";").count}) -le 3) {...} 评估和检查每一行的方法吗?我认为它不会起作用并评估每个行循环的if 条件,而是将整个包装结果作为一个整体。
  • 同意,很难看出他们在那里实际尝试了什么,而且很可能只是假的。但是您可以通过使用$(...) 将语句包装到子表达式中来将语句转换为表达式,我想指出这一点。我通常用它来获取一堆语句作为管道的第一部分,但我敢肯定那里有更奇怪的用例;-)
【解决方案2】:

解决此问题的更符合 PowerShell 习惯的方法是使用 Where-Object 过滤器 cmdlet:

$Lines = Get-Content .\sample.txt |Where-Object { [regex]::Matches($_,';').Count -le 3 }

【讨论】:

    【解决方案3】:
    PS D:\test> (sls -n '(.*;){4}' sample.txt).line
    Text1;Text2;Text3
    Text1;Text2;Text3
    
    # or in long form:
    PS D:\test> Select-String -NotMatch -Pattern '(.*;){4}' -Path .\sample.txt | Select-Object -ExpandProperty Line
    

    正则表达式匹配至少 4 个分号,它们之间有任何内容。 -NotMatch 获取与该正则表达式不匹配的行 - 即少于 4 个分号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 2014-10-26
      • 2015-01-04
      • 1970-01-01
      相关资源
      最近更新 更多