在 PowerShell 中,我尝试过:
alias | select-string Alias
尽管输出中明显包含Alias
,但此方法仍然失败。我知道这是因为select-string正在操作某个对象而不是实际的输出字符串。
有什么解决办法吗?
在 PowerShell 中,我尝试过:
alias | select-string Alias
尽管输出中明显包含Alias
,但此方法仍然失败。我知道这是因为select-string正在操作某个对象而不是实际的输出字符串。
有什么解决办法吗?
我认为这个解决方案更加容易和更好,直接使用函数findstr:
alias | findstr -i Write
你还可以创建一个别名来使用grep命令:
new-alias grep findstr
你的问题在于alias会生成一系列AliasInfo对象,而不是一系列字符串。以下代码可以解决你的问题。
alias | out-string -stream | select-string Alias
或者作为一个函数
function grep {
$input | out-string -stream | select-string $args
}
alias | grep Alias
当你不处理管道中的东西时(比如只运行'alias'命令),shell会使用每个对象的ToString()方法(或者使用ETS信息中指定的输出格式)。
如果您真正想要“grep”格式化的输出(显示字符串),那么请使用Mike的方法。 有时这很方便。但是,如果您想尝试拥抱PowerShell的对象管道本质,请尝试以下方法。首先,请查看流经管道的对象的属性:
PS> alias | Get-Member
TypeName: System.Management.Automation.AliasInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
<snip>
*Definition* Property System.String Definition {get;}
<snip>
请注意Definition属性,这是当您显示Get-Alias(别名)的输出时看到的标题,例如:PS> alias
CommandType Name *Definition*
----------- ---- ----------
Alias % ForEach-Object
<snip>
通常标题名称与属性名称匹配,但并非总是如此。这就是使用 Get-Member 的好处所在。它会向您展示需要“编写脚本”的内容。现在,如果您想要“过滤”的是 Definition 属性内容,则可以考虑使用以下方法。不仅可以过滤该属性的值,而且还可以通过流水线中的每个 AliasInfo 对象来过滤此属性的内容,并且可以使用正则表达式进行过滤。
PS> alias | Where-Object {$_.Definition -match 'alias'}
CommandType Name Definition
----------- ---- ----------
Alias epal Export-Alias
Alias gal Get-Alias
Alias ipal Import-Alias
Alias nal New-Alias
Alias sal Set-Alias
在这个例子中,我使用 Where-Object cmdlet 根据某些任意脚本过滤对象。在这种情况下,我根据 Defintion 属性与正则表达式 "alias" 匹配来进行过滤。只有那些对该筛选器返回 true 的对象才允许向下传播并被格式化以在主机上显示。
顺便说一句,如果您正在键入此命令,则可以使用 Where-Object 的两个别名之一 -“Where”或“?”。例如:
PS> gal | ?{$_.Definition -match '-Item*'}
findstr
命令,由于它不是一个cmdlet而是一个程序,因此PowerShell将为您处理文本转换(仅供完整性;总的来说,根据属性过滤数据通常是更好的选择)。 - Joeygal | Where Definition -match 'alias'
- tkokasih有两个问题。如同问题所述,select-string需要在输出字符串上操作,可以使用"out-string"获取。另外,select-string无法对传递给它的字符串进行逐行操作。以下是通用解决方案。
(alias|out-string) -split "`n" | select-string Write
Get-Member
命令查找正确的属性和表达式,再在where
命令中使用太过繁琐。而grep
在这种情况下特别好用。 - OnesimusUnboundOut-String
上使用“-Stream”参数,然后就可以直接将其管道传递到Select-String。 - Keith HillGet-Alias -Definition Write*
试试这个:
PS C:\> ipconfig /displaydns | Select-String -Pattern 'www.yahoo.com' -Context 0,7
> www.yahoo.com
----------------------------------------
> Record Name . . . . . : www.yahoo.com
Record Type . . . . . : 5
Time To Live . . . . : 27
Data Length . . . . . : 8
Section . . . . . . . : Answer
CNAME Record . . . . : new-fp-shed.wg1.b.yahoo.com
PS> alias | Where-Object {$_.Definition -match 'alias'}
CommandType Name Definition
----------- ---- ----------
Alias epal Export-Alias
Alias gal Get-Alias
Alias ipal Import-Alias
Alias nal New-Alias
Alias sal Set-Alias
那么在PS中,与“匹配”相矛盾的是什么?比如获取某列中不匹配特定值的字段。
如果想要更灵活和懒惰的解决方案,可以匹配对象的所有属性。大多数情况下,这应该能够得到您想要的行为,而当它不起作用时,您总是可以更具体地指定。以下是一个基于此原则工作的grep函数:
Function Select-ObjectPropertyValues {
param(
[Parameter(Mandatory=$true,Position=0)]
[String]
$Pattern,
[Parameter(ValueFromPipeline)]
$input)
$input | Where-Object {($_.PSObject.Properties | Where-Object {$_.Value -match $Pattern} | Measure-Object).count -gt 0} | Write-Output
}
Write
。alias
是Get-Alias
的别名,它是 PowerShell 的一个命令。而Write
实际上是被搜索的字符串,不是我最初因为 PowerShell 命令的彩色格式而认为的Write-Output
的别名。我曾经以为Write-Output
被原地替换以供 findstr 搜索。但实际情况并非如此。每一行Get-Alias
的输出都会被管道传递到 findstr 中,然后 findstr 将在这些字符串中搜索大小写不敏感的搜索词 "Write"。 - Stack of Pancakes