英文:
Powershell: rewrite 1-D array entries from multiple substring cuts
问题
我希望将我的数组分成多个子字符串并重新组合,但是当我尝试组合多个子字符串时,它不起作用。我该如何修复这个问题?
#文件结构:[0-9]{3} [A-Z] [A-Z]{2} [0-9]{2}K[0-9]b [0-9]{2} [A-Z]{2} [A-Z] [0-9]{2} [A-Z]{3}.*
#示例:110 B CC 12K48b 02 SC C 01 BRP
$fileList=@()
$labelStr=@()
$fileList+=(get-childitem -filter *.tif -recurse | Where-Object {$_.name -match '^[0-9]{3} (B|F) [A-Z]{2} ..K..b [0-9]{2}.*'}).Name
$labelStr+=(($fileList.Substring(27,3)+" "+$fileList.Substring(16,2)+" "+$fileList.Substring(0,3)) | Sort-Object | Get-Unique)
$labelStr #我希望数组成员的样子是:BRP 02 110。然而,我得到的是:
你的代码部分已被翻译,如有需要,我可以为你提供更多帮助。
英文:
My array consists of multiple members like the file structure below. I would like to cut each member into multiple substrings and reassemble. I know this works with a single substring cut but when I try to assemble multiple substrings together, it does not work. How might I fix this?
#File Structure: [0-9]{3} [A-Z] [A-Z]{2} [0-9]{2}K[0-9]b [0-9]{2} [A-Z]{2} [A-Z] [0-9]{2} [A-Z]{3}.*
#Example: 110 B CC 12K48b 02 SC C 01 BRP
$fileList=@()
$labelStr=@()
$fileList+=(get-childitem -filter *.tif -recurse | Where-Object {$_.name -match '^[0-9]{3} (B|F) [A-Z]{2} ..K..b [0-9]{2}.*'}).Name
$labelStr+=(($fileList.Substring(27,3)+" "+$fileList.Substring(16,2)+" "+$fileList.Substring(0,3)) | Sort-Object | Get-Unique)
$labelStr #I would expect an array member to look like: BRP 02 110. However, I get:
PS:>
BRP
02
110
答案1
得分: 1
使用单一管道,让 PowerShell 将结果收集到一个数组中:
[array] $labelStr =
(Get-ChildItem -Filter *.tif -Recurse).Name |
Where-Object { $_ -match '^[0-9]{3} (B|F) [A-Z]{2} ..K..b [0-9]{2}\.+$' } |
ForEach-Object {
$_.Substring(27, 3) + " " + $_.Substring(16, 2) + " " + $_.Substring(0, 3)
} |
Sort-Object -Unique
关于你尝试的内容:
$fileList 包含一个文件名数组,当你在该数组上调用 .Substring() 时,它会在该数组的每个元素上调用,结果也成为一个结果数组,这得益于 PowerShell 的成员访问枚举(你还在获取文件名时使用了它的 .Name)。
相反,你必须逐个处理文件名,就像上面所示。
一个尝试使用 .Substring() 调用来反转输入字符串的简化示例:
$names = 'f1', 'f2'
# 错误的示例:直接在数组上操作不会按预期工作。
PS> $names.Substring(1, 1) + $names.Substring(0, 1)
1
2
f
f
# 正确的方式:在每个数组元素上操作。
PS> $names | ForEach-Object { $_.Substring(1, 1) + $_.SubString(0, 1) }
1f
2f
英文:
<!-- language-all: sh -->
Use a single pipeline and let PowerShell collect the results in an array for you:
[array] $labelStr =
(Get-ChildItem -Filter *.tif -Recurse).Name |
Where-Object { $_ -match '^[0-9]{3} (B|F) [A-Z]{2} ..K..b [0-9]{2}\.+$' } |
ForEach-Object {
$_.Substring(27, 3) + " " + $_.Substring(16, 2) + " " + $_.Substring(0, 3)
} |
Sort-Object -Unique
As for what you tried:
$fileList
contains an array of file names, and when you call .Substring()
on that array, it is called on each element of that array, with the results also becoming an array of results, courtesy of PowerShell's member-access enumeration (which you're also using to obtain the file names via .Name
).
Instead, you must process the names one by one, as shown above.
A simplified example that attempts to use .Substring()
calls to reverse the characters in the input string:
$names = 'f1', 'f2'
# WRONG: operating directly on the array doesn't work as expected.
PS> $names.Substring(1, 1) + $names.Substring(0, 1)
1
2
f
f
# OK: operate on each array element.
PS> $names | ForEach-Object { $_.Substring(1, 1) + $_.SubString(0, 1) }
1f
2f
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论