英文:
Powershell convert unordered Text to CSV
问题
Sure, here's the translated content:
我有一个系统,可以导出一个文本文件 [.txt],希望将文本转换为 .csv 文件。导出文件包含500多行,因此在Excel中手动处理非常慢。我无法更改导出格式的方式,因此无法使用分隔符。 😓
以下是导出的示例...
ACC004 门禁控制 29/03/23 9000053641 801MS-0070 滑动 -1 -£391.00 -£255.31
ACC061 门禁自动化 22/03/2023 9000053431 ZL92Z 控制 -1 -£139.50 -83.80
ACC061 门禁自动化 27/03/2023 9000053538 STYLO-ME 摆动 -1 -£191.62 -£113.45
ACT015 活动概念 31/03/2023 9000053739 801MP-0070 摆动 -2 -£324.76 -£238.69
ADI005 ADI Gardner Ltd 29/03/2023 9000053642 806SS-0020 安全 -1 -£46.35 -£28.19
ADI008 ADI Gardner Ltd 31/03/2023 9000053736 AX3024 摆动 -1 -£213.00 -£126.55
ADI011 ADI Gardner Ltd 29/03/2023 9000053591 3199ZM3E 控制 -1 -£112.25 -£64.80
AGD001 AGD Systems Ltd 23/03/2023 9000053465 AX3024 摆动 -1 -£200.65 -£123.79
我的计划是使用PowerShell遍历 .txt 文件的每一行,使用 foreach 循环将行转换为可以写入 CSV 文件的数组。我的难点是如何拆分行,以便将正确的值添加到正确的数组位置...
虽然我可以使用:-
.Substring(0, 6)
来提取字符串开头的 ID [0],但下一个值 [1] 应包含帐户名称,其长度可以是任意字符长度和任意数量的空格。
示例 CSV
ID | 名称 | 日期 | 订单 | 部件 | 类别 | 数量 | 价值 | 调整 |
---|---|---|---|---|---|---|---|---|
ACC004 | 门禁控制 | 29/03/23 | 9000053641 | 801MS-0070 | 滑动 | -1 | -£391.00 | -£255.31 |
ACC061 | 门禁自动化 | 22/03/2023 | 9000053431 | ZL92Z | 控制 | -1 | -£139.50 | -83.80 |
ACC061 | 门禁自动化 | 27/03/2023 | 9000053538 | STYLO-ME | 摆动 | -1 | -£191.62 | -£113.45 |
欢迎提供建议,让乐趣开始吧...
英文:
I have a system that exports a text file [.txt] and wish to convert the text to a .csv file. The export contains 500+ lines so manual manipulation in Excel is very slow. I have no means of changing the way the export is formatted so a delimiter is not possible. 😒
Below is an example of the export...
ACC004 Access Control 29/03/23 9000053641 801MS-0070 Sliding -1 -£391.00 -£255.31
ACC061 Access Automation 22/03/2023 9000053431 ZL92Z Control -1 -£139.50 -83.80
ACC061 Access Automation 27/03/2023 9000053538 STYLO-ME Swing -1 -£191.62 -£113.45
ACT015 Active Concept 31/03/2023 9000053739 801MP-0070 Swing -2 -£324.76 -£238.69
ADI005 ADI Gardner Ltd 29/03/2023 9000053642 806SS-0020 Safety -1 -£46.35 -£28.19
ADI008 ADI Gardner Ltd 31/03/2023 9000053736 AX3024 Swing -1 -£213.00 -£126.55
ADI011 ADI Gardner Ltd 29/03/2023 9000053591 3199ZM3E Control -1 -£112.25 -£64.80
AGD001 AGD Systems Ltd 23/03/2023 9000053465 AX3024 Swing -1 -£200.65 -£123.79
My plan is to use PowerShell to iterate through each line of the .txt file with a foreach loop and convert the line into an array that can be written to a CSV file. My stumbling block is how to split the row so that the correct values are added to the correct array positions...
Whilst I can use:-
.Substring(0, 6)
To pull the ID [0] from the start of the string the next value [1] should contain the account name which can be any character length and any number of spaces.
Example CSV
ID | Name | Date | Order | Part | Cat | Qty | Val | Adj |
---|---|---|---|---|---|---|---|---|
ACC004 | Access Control | 29/03/23 | 9000053641 | 801MS-0070 | Sliding | -1 | -£391.00 | -£255.31 |
ACC061 | Access Automation | 22/03/2023 | 9000053431 | ZL92Z | Control | -1 | -£139.50 | -83.80 |
ACC061 | Access Automation | 27/03/2023 | 9000053538 | STYLO-ME | Swing | -1 | -£191.62 | -£113.45 |
Any suggestions would be gladly received, So the fun begins...
答案1
得分: 2
以下是使用正则表达式的代码示例:
$text = @"
ACC004 Access Control 29/03/23 9000053641 801MS-0070 Sliding -1 -£391.00 -£255.31
ACC061 Access Automation 22/03/2023 9000053431 ZL92Z Control -1 -£139.50 -83.80
ACC061 Access Automation 27/03/2023 9000053538 STYLO-ME Swing -1 -£191.62 -£113.45
ACT015 Active Concept 31/03/2023 9000053739 801MP-0070 Swing -2 -£324.76 -£238.69
ADI005 ADI Gardner Ltd 29/03/2023 9000053642 806SS-0020 Safety -1 -£46.35 -£28.19
ADI008 ADI Gardner Ltd 31/03/2023 9000053736 AX3024 Swing -1 -£213.00 -£126.55
ADI011 ADI Gardner Ltd 29/03/2023 9000053591 3199ZM3E Control -1 -£112.25 -£64.80
AGD001 AGD Systems Ltd 23/03/2023 9000053465 AX3024 Swing -1 -£200.65 -£123.79
"@
$pattern = "^(?<id>[^\s]+)\s+(?<name>.*) (?<date>\d{2}/\d{2}/\d+)\s+(?<order>\d+)\s+(?<part>[^\s]+)\s+(?<cat>.*)\s+(?<qty>.\d+)\s+(?<val>[^\s]+)\s+(?<adj>.*)""
$reader = [System.IO.StringReader]::new($text)
$table = [System.Collections.ArrayList]::new()
while(($line = $reader.ReadLine()) -ne $null)
{
$line -match $pattern | Out-Null
$id = $Matches.id.Trim()
$name = $Matches.name.Trim()
$date = $Matches.date.Trim()
$order = $Matches.order.Trim()
$part = $Matches.part.Trim()
$cat = $Matches.cat.Trim()
$qty = $Matches.qty.Trim()
$val = $Matches.val.Trim()
$adj = $Matches.adj.Trim()
$newRow = [PSCustomObject]@{
ID = $id
Name = $name
Date = $date
Order = $order
Part = $part
Cat = $cat
Qty = $qty
Val = $val
Adj = $adj
}
$table.Add($newRow) | Out-Null
}
$table | format-list
$table | export-csv 'c:\temp\test.csv'
希望这有帮助!
英文:
Try following code which uses Regex
<!-- begin snippet: js hide: false console: true babel: false -->
$text = @"
ACC004 Access Control 29/03/23 9000053641 801MS-0070 Sliding -1 -£391.00 -£255.31
ACC061 Access Automation 22/03/2023 9000053431 ZL92Z Control -1 -£139.50 -83.80
ACC061 Access Automation 27/03/2023 9000053538 STYLO-ME Swing -1 -£191.62 -£113.45
ACT015 Active Concept 31/03/2023 9000053739 801MP-0070 Swing -2 -£324.76 -£238.69
ADI005 ADI Gardner Ltd 29/03/2023 9000053642 806SS-0020 Safety -1 -£46.35 -£28.19
ADI008 ADI Gardner Ltd 31/03/2023 9000053736 AX3024 Swing -1 -£213.00 -£126.55
ADI011 ADI Gardner Ltd 29/03/2023 9000053591 3199ZM3E Control -1 -£112.25 -£64.80
AGD001 AGD Systems Ltd 23/03/2023 9000053465 AX3024 Swing -1 -£200.65 -£123.79
"@
$pattern = "^(?<id>[^\s]+)\s+(?<name>.*)(?<date>\d{2}/\d{2}/\d+)\s+(?<order>\d+)\s+(?<part>[^\s]+)\s+(?<cat>.*)\s+(?<qty>.\d+)\s+(?<val>[^\s]+)\s+(?<adj>.*)"
$reader = [System.IO.StringReader]::new($text)
$table = [System.Collections.ArrayList]::new()
while(($line = $reader.ReadLine()) -ne $null)
{
$line -match $pattern | Out-Null
$id = $Matches.id.Trim()
$name = $Matches.name.Trim()
$date = $Matches.date.Trim()
$order = $Matches.order.Trim()
$part = $Matches.part.Trim()
$cat = $Matches.cat.Trim()
$qty = $Matches.qty.Trim()
$val = $Matches.val.Trim()
$adj = $Matches.adj.Trim()
$newRow = [PSCustomObject]@{
ID = $id
Name = $name
Date = $date
Order = $order
Part = $part
Cat = $cat
Qty = $qty
Val = $val
Adj = $adj
}
$table.Add($newRow) | Out-Null
}
$table | format-list
$table | export-csv 'c:\temp\test.csv'
<!-- end snippet -->
答案2
得分: 0
你可以使用split来分割数据,然后使用正则表达式来搜索日期。一旦找到日期,你就知道前面的部分是账户和ID。由于ID似乎是一个“Word”,你可以知道在ID和日期之间的“Words”是你的账户名称。
英文:
Looking at your data. You could use split to split them up, then use a regex expression to search for the date. Once you found the date you know the ones prior are the account and id. Since ID seems to be one "Word" you know the "Words" between ID and date are your account name.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论