为什么我需要两组双引号才能在 powershell 中使用 find?

为什么我需要两组双引号才能在 powershell 中使用 find?

为什么我需要两组双引号才能在 powershell 中使用 find?

例如

这里尝试像在 cmd.exe 中一样使用 FIND,但出现错误。

PS C:\Users\User> echo abc | find "a"
FIND: Parameter format not correct

PS C:\Users\User> find "a" a.a
FIND: Parameter format not correct
PS C:\Users\User>

必须做

PS C:\Users\User> echo "abc" | find "`"a`""
abc
PS C:\Users\User>

(反引号是 powershell 中的转义字符)

因此,您需要两组双引号。一组是经过转义的内部引号(内部对中的两个引号均经过转义),另一组是外部引号。

ECHO 或 DIR 不需要转义引号。(尽管它们被授予 shell 内部的权限),因此更像 FIND 的示例可能是 XCOPY。

xcopy 是一个外部命令,find 也是,不过 xcopy 不需要这种东西。一组双引号不转义就可以了。

PS C:\Users\User> xcopy "a.a" "b.b"
Does b.b specify a file name
or directory name on the target
(F = file, D = directory)? f
C:a.a
1 File(s) copied
PS C:\Users\User>

答案1

find为什么在 Powershell 中使用时需要两组双引号?

xcopy 不需要那种东西。一组双引号不需要转义就可以了。

这是因为引号xcopy选修的(除非源字符串或目标字符串包含空格)

中的引文find强制性的

"string" :必需。指定要搜索的字符组。必须将字符串括在引号中(即"string")。

来源查找 | Microsoft Docs

和:

PowerShell 正在删除外部引号

来源windows - PowerShell从命令行参数中去除双引号 - 堆栈内存溢出

这一切之前已经向您解释过了,请看您的以前的问题cmd.exe - 为什么“find”不能在 PowerShell 中使用? - 超级用户


进一步阅读

答案2

为什么要将 PowerShell 别名与 DOS 可执行文件 (find.exe) 混合?

DOS/cmd.exe 命令有要求。这就是您遇到问题的原因。许多 cmd.exe/DOS 命令根本没有引号,有些则没有。

在 PowerShell 中,简单字符串不需要双引号。当变量包含在字符串和其他一些格式实例中时,需要使用双引号进行变量扩展,但这不是您要执行的操作。

您使用的是 Powershell,因此最好使用 PowerShell 方式执行此操作。如果这是一次性代码或交互式控制台等内容,则可以使用别名,但不要在函数、脚本、模块(即生产代码)中使用别名。

根据微软的说法:

• 别名的最佳实践 在 PowerShell 脚本中使用别名的最佳实践 https://devblogs.microsoft.com/scripting/best-practice-for-using-aliases-in-powershell-scripts https://devblogs.microsoft.com/scripting/using-powershell-aliases-best-practices

为什么首先要担心别名?

使用别名到底有什么大不了的?如果别名可以让代码更易于输入,那么在脚本中使用别名有什么坏处呢?对于脚本来说,有两个因素在起作用。首先,没有别名是一定存在的 — 即使是 Windows PowerShell 创建的别名也是如此。

所以这 ...

echo abc | find "a"

...应该是这个...

Get-Alias -Name echo | 
Format-Table -AutoSize
# Results
<#
CommandType Name                 Version Source
----------- ----                 ------- ------
Alias       echo -> Write-Output
#>

Write-Output -Object 'abc' | Select-Object 'a'

或这个...

Write-Output -Object 'abc' | Select-String -Pattern 'a'

或这个...

Select-String -Pattern 'a' -InputObject 'abc'

# Results
<#
abc
#>

Get-Alias -Name echo | Format-Table -AutoSize
# Results

<#
CommandType Name                 Version Source
----------- ----                 ------- ------
Alias       echo -> Write-Output     
#>

Get-Alias -Name xcopy | Format-Table -AutoSize
# Results
<#
Get-Alias : This command cannot find a matching alias because an alias with the name 'xcopy' does not exist.
At line:1 char:1
+ Get-Alias -Name xcopy | Format-Table -AutoSize
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (xcopy:String) [Get-Alias], ItemNotFoundException
    + FullyQualifiedErrorId : ItemNotFoundException,Microsoft.PowerShell.Commands.GetAliasCommand   
#>

As you can see the above is using cmd.exe/DOS executable, not an alias


So, change to this.

# Get specifics for a module, cmdlet, or function
(Get-Command -Name Copy-Item).Parameters
(Get-Command -Name Copy-Item).Parameters.Keys
Get-help -Name Copy-Item -Examples
Get-help -Name Copy-Item -Full
Get-help -Name Copy-Item -Online


'*.txt', '*.xls' | 
ForEach-Object {
    Copy-Item -Path "d:\temp\$PSItem" -Destination 'D:\Temp\ChildFolder' -WhatIf
}
# Results
<#
What if: Performing the operation "Copy File" on target "Item: D:\temp\abc.txt Destination: D:\Temp\ChildFolder\abc.txt".
What if: Performing the operation "Copy File" on target "Item: D:\temp\account.txt Destination: D:\Temp\ChildFolder\account.txt".
...
#>

关于命令优先权

如果您未指定路径,PowerShell 在对当前会话中加载的所有项目运行命令时将使用以下优先顺序:

1 - 别名

2 - 功能

3 - 命令

4 – 外部可执行文件

(程序和非 PowerShell 脚本)

因此,如果您输入“help”,PowerShell 首先会查找名为 help 的别名,然后查找名为 Help 的函数,最后查找名为 Help 的 cmdlet。它会运行找到的第一个帮助项。

例如,如果您的会话包含一个 cmdlet 和一个函数,均名为 Get-Map,则当您键入 Get-Map 时,PowerShell 会运行该函数。

是的,您可以在 PowerShell 命令或脚本中使用 cmd.exe/DOS 可执行文件,但这样做时,它们必须符合 cmd.exe/DOS 规定。从 Powershell 调用外部可执行文件是一件有据可查的事情。

• PowerShell:运行可执行文件 https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

尽量避免在 PowerShell 脚本中混合使用 cmd.exe/DOS 可执行文件,而使用 PowerShell 等效程序。注意:有时无法避免这种情况,但根据发布的使用情况并非如此。

更新 根据您的评论

write-host abc | select-string -pattern "a" 显示预期结果

  • abc。但不幸的是这也显示了 abc。write-host abc | select-string -pattern "z"

那应该是 Write-Output,而不是 Write-Host,修正了以上内容。

您所做的事情根本不需要 Write-Host 或 Write-Output。除非您另有说明,否则输出到屏幕是 PoweShell 的默认设置。如果您说您只想要字符串中的字母“a”,那么您需要将其作为数组传递,而不是单个字符串

'a','b','c' | 
Select-String -Pattern 'a'
# Results
<#
a
#>

'a','b','c' | 
Select-String -Pattern 'z'
# Results
<#

#>

这是将单个字符串拆分为数组的另一种方法。

('abc').ToCharArray() | 
Select-String -Pattern 'a'

您也可以直接使用 .Net 命名空间

[regex]::Match('abc','a').Value
# Results
<#
a
#>

[regex]::Match('abc','z').Value
# Results
<#

#>

PowerShell 是一种面向对象的语言,默认情况下期望和发出对象,而不是字符串。

您可以将事物转换为字符串或以几种不同的方式传递字符串,以满足比较、匹配和报告需求。

相关内容