为什么我需要两组双引号才能在 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"
)。
和:
PowerShell 正在删除外部引号
来源windows - PowerShell从命令行参数中去除双引号 - 堆栈内存溢出
这一切之前已经向您解释过了,请看您的以前的问题cmd.exe - 为什么“find”不能在 PowerShell 中使用? - 超级用户
进一步阅读
- 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 是一种面向对象的语言,默认情况下期望和发出对象,而不是字符串。
您可以将事物转换为字符串或以几种不同的方式传递字符串,以满足比较、匹配和报告需求。