假设我有一个像这样的字符串集合,没有特定的顺序:
"Filename (Text) (Comment)"
"Filename (Word) (1)"
"Filename (Word) (1) (Bad)"
"Filename (Text) (2)"
"Filename (Picture)"
"Filename (Misc)"
"Filename (Misc) (1)"
"Filename (Picture) (1)"
"Filename (Audio)"
"Filename (Audio) (Comment) (1)"
我想这样对它们进行排序:
"Filename (Text) (2)"
"Filename (Word) (1)"
"Filename (Text) (Comment)"
"Filename (Audio) (Comment) (1)"
"Filename (Audio)"
"Filename (Picture) (1)"
"Filename (Picture)"
"Filename (Misc) (1)"
"Filename (Misc)"
"Filename (Word) (1) (Bad)"
换句话说,我想按以下顺序排序:(Bad)到底部(文本/单词、音频、图片),在(Bad)之上,然后按(2, 1, [空白])排序。
请注意,我希望 Text 和 Word 聚集在一起,然后按括号中的数字排序,并且我不关心任何与这些不匹配的内容,所以我不关心(评论)。
目前我得到这个:
"Filename (Word) (1)"
"Filename (Text) (2)"
"Filename (Text) (Comment)"
"Filename (Audio) (Comment) (1)"
"Filename (Audio)"
"Filename (Picture) (1)"
"Filename (Picture)"
"Filename (Misc) (1)"
"Filename (Misc)"
"Filename (Word) (1) (Bad)"
所以我已经非常接近得到我想要的了。
这就是我正在做的:
$badExpression = { if ($_ -match '\((Bad)\)') { $matches[1] } }
$documentExpression = { if ($_ -match '\((Text|Word)\)') { $matches[1] } }
$soundExpression = { if ($_ -match '\((Audio)\)') { $matches[1] } }
$imageExpression = { if ($_ -match '\((Picture)\)') { $matches[1] } }
$numberExpression = { if ($_ -match '\((2|1)\)') { $matches[1] } }
"Filename (Text) (Comment)", "Filename (Word) (1)", "Filename (Word) (1) (Bad)", `
"Filename (Text) (2)", "Filename (Picture)", "Filename (Misc)", "Filename (Misc) (1)", `
"Filename (Picture) (1)", "Filename (Audio)", "Filename (Audio) (Comment) (1)" | Sort-Object `
@{Expression = $badExpression; Descending = $false}, `
@{Expression = $documentExpression; Descending = $true}, `
@{Expression = $soundExpression; Descending = $true}, `
@{Expression = $imageExpression; Descending = $true}, `
@{Expression = $numberExpression; Descending = $true}
我肯定误解了我的表达式到底是如何应用于排序的。我有预感,也许我必须执行一系列排序对象,但我无法真正弄清楚是什么。
只是为了吸引焦点:我遇到的问题是(Word)和(文本)应该被排序,就好像它们是相同的一样。
编辑:好的,我想我现在得到了我想要的行为,这是一个微妙的变化,请参阅我添加的 -replace。
$badExpression = { if ($_ -match '\((Bad)\)') { $matches[1] } }
$documentExpression = { if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} }
$soundExpression = { if ($_ -match '\((Audio)\)') { $matches[1] } }
$imageExpression = { if ($_ -match '\((Picture)\)') { $matches[1] } }
$numberExpression = { if ($_ -match '\((2|1)\)') { $matches[1] } }
"Filename (Text) (Comment)", "Filename (Word) (1)", "Filename (Word) (1) (Bad)", `
"Filename (Text) (2)", "Filename (Picture)", "Filename (Misc)", "Filename (Misc) (1)", `
"Filename (Picture) (1)", "Filename (Audio)", "Filename (Audio) (Comment) (1)" | Sort-Object `
@{Expression = $badExpression; Descending = $false}, `
@{Expression = $documentExpression; Descending = $true}, `
@{Expression = $soundExpression; Descending = $true}, `
@{Expression = $imageExpression; Descending = $true}, `
@{Expression = $numberExpression; Descending = $true}
所以对于互联网点:我的脚本在做什么(除了工作之外),我想更好地理解它。 :) 我理解松散地发生了什么,但我想更好地掌握它。
这并不简单。但我更愿意先将其排序为Natural。
Get-Content C:\folder\String.txt | Sort-Object $ToNatural
那么至少你会直接得到这样的O/p(按音频、杂项、图片、文本排序):
"Filename (Audio) (Comment) (1)"
"Filename (Audio)"
"Filename (Misc) (1)"
"Filename (Misc)"
"Filename (Picture) (1)"
"Filename (Picture)"
"Filename (Text) (2)"
"Filename (Text) (Comment)"
"Filename (Word) (1) (Bad)"
"Filename (Word) (1)"
之后您可以根据您的需要使用一些正则表达式来匹配。让我知道这种方法是否对您有帮助。
迟了六年,我被相关侧边栏狙击,而不是做真正的工作...
("Filename (Text) (Comment)", "Filename (Word) (1)",
"Filename (Word) (1) (Bad)", "Filename (Text) (2)",
"Filename (Picture)", "AAAAname (Misc)",
"Filename (Misc) (1)", "Filename (Picture) (1)",
"Filename (Audio)", "Filename (Audio) (Comment) (1)") `
| Sort-Object -Property `
@{Descending=$true; Expression={ switch -Regex ($_) { # reverse-sort by a numerical code
'\(bad\)' { -2; break } # push (bad) to the bottom (lowest code val)
'\((text|word)\)' { 80; break } # (text) or (word) come first (highest code val)
'\(audio\)' { 60; break }
'\(picture\)' { 40; break }
'\(misc\)' { 20; break }
default { -1 } # unknowns are penultimate (second-lowest code val)
}}},
@{Descending=$true; Expression={ switch -Regex ($_) { #...then reverse-sort by the first (num)
'\(([0-9]+)\)' { [Int32]($Matches[1]) } # find any run of digits and convert to integer
default { -1 } # assume no negative (nums)
}}}
Filename (Text) (2) Filename (Word) (1) Filename (Text) (Comment) Filename (Audio) (Comment) (1) Filename (Audio) Filename (Picture) (1) Filename (Picture) Filename (Misc) (1) Filename (Misc) Filename (Word) (1) (Bad)
上面假设您对
(Bad)
的存在比其他任何东西都感兴趣,然后是您命名的 (Class)
值之一的 first实例,然后是 first
(number)
。多个类/多个数字是不确定的。
您也没有指出是否要对实际的
Filename
文本本身进行排序,因此,在上面,它也是不确定的。如果您did也想对Filename
文本进行排序,请尝试...
("Filename (Text) (Comment)", "Filename (Word) (1)",
"Filename (Word) (1) (Bad)", "Filename (Text) (2)",
"Filename (Picture)", "AAAAname (Misc)",
"Filename (Misc) (1)", "Filename (Picture) (1)",
"Filename (Audio)", "Filename (Audio) (Comment) (1)") `
| Sort-Object -Property `
@{Expression={
($_ -split '\(')[0] # first, sort by everything up to the first (
}},
@{Descending=$true; Expression={ switch -Regex ($_) { #...then reverse-sort by a numerical code
'\(bad\)' { -2; break } # push (bad) to the bottom (lowest code val)
'\((text|word)\)' { 80; break } # (text) or (word) come first (highest code val)
'\(audio\)' { 60; break }
'\(picture\)' { 40; break }
'\(misc\)' { 20; break }
default { -1 } # unknowns are penultimate (second-lowest code val)
}}},
@{Descending=$true; Expression={ switch -Regex ($_) { #...finally reverse-sort by the first (num)
'\(([0-9]+)\)' { [Int32]($Matches[1]) } # find any run of digits and convert to integer
default { -1 } # assume no negative (nums)
}}}
AAAAname (Misc) Filename (Text) (2) Filename (Word) (1) Filename (Text) (Comment) Filename (Audio) (Comment) (1) Filename (Audio) Filename (Picture) (1) Filename (Picture) Filename (Misc) (1) Filename (Word) (1) (Bad)
对于互联网点:我的脚本在做什么......
$badExpression = { if ($_ -match '\((Bad)\)') { $matches[1] } } $documentExpression = { if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} } $soundExpression = { if ($_ -match '\((Audio)\)') { $matches[1] } } $imageExpression = { if ($_ -match '\((Picture)\)') { $matches[1] } } $numberExpression = { if ($_ -match '\((2|1)\)') { $matches[1] } } "Filename (Text) (Comment)", "Filename (Word) (1)", "Filename (Word) (1) (Bad)", ` "Filename (Text) (2)", "Filename (Picture)", "Filename (Misc)", "Filename (Misc) (1)", ` "Filename (Picture) (1)", "Filename (Audio)", "Filename (Audio) (Comment) (1)" | Sort-Object ` @{Expression = $badExpression; Descending = $false}, ` @{Expression = $documentExpression; Descending = $true}, ` @{Expression = $soundExpression; Descending = $true}, ` @{Expression = $imageExpression; Descending = $true}, ` @{Expression = $numberExpression; Descending = $true}
您的
$expression
变量每个都存储一个脚本块,该脚本块将返回特定单词,if在当前管道项中找到该单词;例如如果管道项 ($badExpression
) 包含“(Bad)”,则 Bad
中的脚本将返回 $_
,如果不包含“(Bad)”,则不返回任何内容。在任何 . 中,没有任何内容出现在
Bad
之前。
您的
Sort-Object
依次对每个表达式的列表进行排序。对于每个字符串,这会提取以下内容:
$_ : Filename (Text) (Comment)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} : DocumentDocument
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } :
$_ : Filename (Word) (1)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} : DocumentDocument
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } : 1
$_ : Filename (Word) (1) (Bad)
if ($_ -match '\((Bad)\)') { $matches[1] } : Bad
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} : DocumentDocument
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } : 1
$_ : Filename (Text) (2)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} : DocumentDocument
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } : 2
$_ : Filename (Picture)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} :
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } : Picture
if ($_ -match '\((2|1)\)') { $matches[1] } :
$_ : Filename (Misc)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} :
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } :
$_ : Filename (Misc) (1)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} :
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } : 1
$_ : Filename (Picture) (1)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} :
if ($_ -match '\((Audio)\)') { $matches[1] } :
if ($_ -match '\((Picture)\)') { $matches[1] } : Picture
if ($_ -match '\((2|1)\)') { $matches[1] } : 1
$_ : Filename (Audio)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} :
if ($_ -match '\((Audio)\)') { $matches[1] } : Audio
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } :
$_ : Filename (Audio) (Comment) (1)
if ($_ -match '\((Bad)\)') { $matches[1] } :
if ($_ -match '\((Text|Word)\)') { $matches[1] -replace ".*",'Document'} :
if ($_ -match '\((Audio)\)') { $matches[1] } : Audio
if ($_ -match '\((Picture)\)') { $matches[1] } :
if ($_ -match '\((2|1)\)') { $matches[1] } : 1
$expression
脚本有些迂回,因为只要它是二进制的(存在与不存在),它们返回什么并不重要。如果您愿意,您可以轻松地将其中的大部分替换为 { $_ -match '\(...\) }'
部分,并对生成的布尔值进行排序。
您的第一种方法将
(Text)
排序在 (Word)
之前的原因是因为这就是您要求它在到达该表达式时进行排序的内容。 $documentExpression
返回与 $matches[1]
匹配的术语,\((Text|Word)\)
表示该术语可以是 Text
或 Word
。因此,您的排序是在三个可能的术语(Word
、Text
或无)上完成的,而不是在两个(存在、不存在)上完成的。
您的
$documentExpression
的第二个版本采用 $Matches[1]
中的任何术语,丢弃它并用 DocumentDocument
替换它,这将其解析回二进制存在/不存在条件。
(它用
DocumentDocument
而不是仅仅 Document
来代替它是很奇怪的。我最好的猜测是 -match
和 -replace
之间存在竞争条件 - 两个运算符通常都会填充 $Matches
,并且同时读取值和写入可能会令人窒息。)
$numberExpression
是唯一合理地期望具有多个要排序的值的表达式,因为您要求 1
或 2
,因此对 $Matches[1]
进行排序是有意义的。