Powershell - 将 .txt 数据输出到 CSV
Powershell - Outputting .txt data to CSV
希望您能帮助 PowerShell 初学者将数据从 .txt 文件输出到 CSV。
注意事项:
- 每个文本文件都包含多个需要提取的条目
- 终端始终是 A 后跟 3 位数字
- 询问者总是以 C 开头,但可以是不同的长度
- 文件中有两种出生日期模式
- txt 中的空格不是用制表符分隔的,它们的间距也不相同。
这是我想要的 CSV 输出(抱歉,我没有足够的代表来上传图片!)
+------------+------+----------+----------+-------------------+----------+
| Date | Time | Terminal | Enquirer | Enquiry | DOB |
+------------+------+----------+----------+-------------------+----------+
| 29/05/2017 | 1227 | A999 | CA75849 | DOE/JOHN | / /1988 |
+------------+------+----------+----------+-------------------+----------+
| 29/05/2017 | 1424 | A999 | CA75849 | SMITH/SIMON/PETER | / /1967 |
+------------+------+----------+----------+-------------------+----------+
| | | | | | |
+------------+------+----------+----------+-------------------+----------+
数据 .txt 文件示例
START TERMINAL USER ENQUIRER TERMINAL IP
========================================================================================================================
29/05/17 1227 A999 CA75849 8875849 OCBA NCPS RBC/12/1960
SEARCH REF NAME : DOE/JOHN PAGE CODE =
DATE OF BIRTH : / /1988
========================================================================================================================
29/05/17 1424 A999 CA75849 8875849 OCBA NCPS RBC/60/2111
SEARCH REF NAME : SMITH/SIMON/PETER CHAPTER CODE =
DATE OF BIRTH : / /1967
========================================================================================================================
请不要被我的垃圾 Powershell 脚本吓倒。
我设法获得的最好结果是在单元格中获得正确的信息,但 'System.Object[]' 而不是实际的结果字符串。
$XmlDocument = Get-Content -Path "C:\Script Projects\Log0006.txt"
$TodaysCSV = "C:\Script Projects\Log0006.csv"
$TopLine = $XmlDocument | Select-String "A1"
$Enquiry = $XmlDocument | Select-String "Search"
$DOB = $XmlDocument | Select-String "BIRTH"
$toptop = $topline -split " "
$Date = $toptop | Select-String -Pattern "^\d{2}/\d{2}/\d{2}$"
$Time = $toptop | Select-String -Pattern "^\d{4}$"
$Terminal = $toptop | Select-String -Pattern "^A\d{3}$"
$Enquirer = $toptop | Select-String -Pattern "C\w\d{5}"
$csv = New-Object -TypeName PSObject
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Date" -Value $Date
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Time" -Value $Time
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Terminal" -value $Terminal
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Enquirer" -value $Enquirer
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Enquiry" -value $Enquiry
Add-Member -InputObject $csv -MemberType NoteProperty -Name "DOB" -value $DOB
$csv | Export-Csv $TodaysCSV -NoTypeInformation
我得到这个输出
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| Date | Time | Terminal | Enquirer | Enquiry | DOB |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| System.Object[] | System.Object[] | System.Object[] | System.Object[] | System.Object[] | System.Object[] |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| | | | | | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| | | | | | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
我也尝试过这种方式,但我只能获取日期或玩弄我可以获得所有数据,但只能在单个列中
$Total2 = "$date2", "$time2", "$Terminal2", "$Enquirer", "$Enquiry"
$Columns = "Date", "Time", "Terminal", "Enquirer", "Enquiry"
$total2 | ConvertFrom-Csv -Header $Columns| export-csv $TodaysCSV -NoTypeInformation
但不记得我是怎么做到的,如果我从该文件导入回 PowerShell 并导出为 CSV,我仍然不会让我水平显示它。
我设法得到的最好的是这个
Date
----
29/05/17
29/05/17
Time
----
1227
1424
Terminal
--------
A999
A999
Enquirer
--------
CA75849
CA75849
Enquiry
-------
SEARCH REF NAME : DOE/JOHN CHAPTER CODE =
SEARCH REF NAME : SMITH/SIMON/PETER CHAPTER CODE =
提前感谢您的帮助!
这里的问题是在导出之前需要将对象转换为字符串。
要使您的代码正常工作,您可以稍微修改对象创建:
$csv = @()
for ($i = 0;$i -lt $Date.Length; $i++) {
$obj = New-Object -TypeName PSObject
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Date" -Value $Date[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Time" -Value $Time[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Terminal" -value $Terminal[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Enquirer" -value $Enquirer[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Enquiry" -value $Enquiry[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "DOB" -value $DOB[$i]
$csv += $obj
}
解释:
这里的问题是你试图创建一个数组对象,而你应该创建一个对象数组。这就是为什么在导出时得到 System.Object[]
而不是预期值的原因。
注意:看看你粘贴在这里的代码和文件格式。这一行:
$TopLine = $XmlDocument | Select-String "A1"
应该是
$TopLine = $XmlDocument | Select-String "A999"
我使用了不同的方法,
- 将文件拆分为以虚线和
分隔的部分
- 3 个不同的正则表达式使用命名(捕获组)来 grep 每种线型的属性。
第一个在 RegEx101.com
- 所有找到的属性都存储在一个中间 $Row 对象中,如果所有 RegEx 匹配则收集在
$Csv
## Q:\Test18\SO_51209341.ps1
$FileIn = '.\SO_51209341_data.txt'
$TodayCsv = '.\SO_51209341_data.csv'
$RE1 = [RegEx]'(?m)(?<Date>\d{2}\/\d{2}\/\d{2}) (?<Time>\d{4}) +(?<Terminal>A\d{3}) +(?<User>C[A-Z0-9]+) +(?<Enquirer>.*)$'
$RE2 = [RegEx]'\s+SEARCH REF\s+NAME : (?<Enquiry>.+?) (PAGE|CHAPTER) CODE ='
$RE3 = [RegEx]'\s+DATE OF BIRTH : (?<DOB>[0-9 /]+?/\d{4})'
$Sections = (Get-Content $FileIn -Raw) -split "={30,}`r?`n" -ne ''
$Csv = ForEach($Section in $Sections){
$Row= @{} | Select-Object Date,Time,Terminal,User,Enquirer,Enquiry,DOB
$Cnt = 0
If ($Section -match $RE1){++$Cnt
$Row.Date = $Matches.Date
$Row.Time = $Matches.Time
$Row.Terminal = $Matches.Terminal
$Row.User = $Matches.User
$Row.Enquirer = $Matches.Enquirer.Trim()
}
If ($Section -match $RE2){++$Cnt
$Row.Enquiry = $Matches.Enquiry
}
If ($Section -match $RE3){++$Cnt
$Row.DOB = $Matches.DOB
}
if ($Cnt -eq 3){$Row}
}
$csv | Format-Table
$csv | Export-Csv $Todaycsv -NoTypeInformation
示例输出修订版
> . Q:\Test18\SO_51209341.ps1
Date Time Terminal User Enquirer Enquiry DOB
---- ---- -------- ---- -------- ------- ---
29/05/17 1227 A999 CA75849 8875849 OCBA NCPS RBC/12/1960 DOE/JOHN / /1988
29/05/17 1424 A999 CA75849 8875849 OCBA NCPS RBC/60/2111 SMITH/SIMON/PETER / /1967
希望您能帮助 PowerShell 初学者将数据从 .txt 文件输出到 CSV。
注意事项:
- 每个文本文件都包含多个需要提取的条目
- 终端始终是 A 后跟 3 位数字
- 询问者总是以 C 开头,但可以是不同的长度
- 文件中有两种出生日期模式
- txt 中的空格不是用制表符分隔的,它们的间距也不相同。
这是我想要的 CSV 输出(抱歉,我没有足够的代表来上传图片!)
+------------+------+----------+----------+-------------------+----------+
| Date | Time | Terminal | Enquirer | Enquiry | DOB |
+------------+------+----------+----------+-------------------+----------+
| 29/05/2017 | 1227 | A999 | CA75849 | DOE/JOHN | / /1988 |
+------------+------+----------+----------+-------------------+----------+
| 29/05/2017 | 1424 | A999 | CA75849 | SMITH/SIMON/PETER | / /1967 |
+------------+------+----------+----------+-------------------+----------+
| | | | | | |
+------------+------+----------+----------+-------------------+----------+
数据 .txt 文件示例
START TERMINAL USER ENQUIRER TERMINAL IP
========================================================================================================================
29/05/17 1227 A999 CA75849 8875849 OCBA NCPS RBC/12/1960
SEARCH REF NAME : DOE/JOHN PAGE CODE =
DATE OF BIRTH : / /1988
========================================================================================================================
29/05/17 1424 A999 CA75849 8875849 OCBA NCPS RBC/60/2111
SEARCH REF NAME : SMITH/SIMON/PETER CHAPTER CODE =
DATE OF BIRTH : / /1967
========================================================================================================================
请不要被我的垃圾 Powershell 脚本吓倒。
我设法获得的最好结果是在单元格中获得正确的信息,但 'System.Object[]' 而不是实际的结果字符串。
$XmlDocument = Get-Content -Path "C:\Script Projects\Log0006.txt"
$TodaysCSV = "C:\Script Projects\Log0006.csv"
$TopLine = $XmlDocument | Select-String "A1"
$Enquiry = $XmlDocument | Select-String "Search"
$DOB = $XmlDocument | Select-String "BIRTH"
$toptop = $topline -split " "
$Date = $toptop | Select-String -Pattern "^\d{2}/\d{2}/\d{2}$"
$Time = $toptop | Select-String -Pattern "^\d{4}$"
$Terminal = $toptop | Select-String -Pattern "^A\d{3}$"
$Enquirer = $toptop | Select-String -Pattern "C\w\d{5}"
$csv = New-Object -TypeName PSObject
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Date" -Value $Date
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Time" -Value $Time
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Terminal" -value $Terminal
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Enquirer" -value $Enquirer
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Enquiry" -value $Enquiry
Add-Member -InputObject $csv -MemberType NoteProperty -Name "DOB" -value $DOB
$csv | Export-Csv $TodaysCSV -NoTypeInformation
我得到这个输出
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| Date | Time | Terminal | Enquirer | Enquiry | DOB |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| System.Object[] | System.Object[] | System.Object[] | System.Object[] | System.Object[] | System.Object[] |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| | | | | | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| | | | | | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
我也尝试过这种方式,但我只能获取日期或玩弄我可以获得所有数据,但只能在单个列中
$Total2 = "$date2", "$time2", "$Terminal2", "$Enquirer", "$Enquiry"
$Columns = "Date", "Time", "Terminal", "Enquirer", "Enquiry"
$total2 | ConvertFrom-Csv -Header $Columns| export-csv $TodaysCSV -NoTypeInformation
但不记得我是怎么做到的,如果我从该文件导入回 PowerShell 并导出为 CSV,我仍然不会让我水平显示它。
我设法得到的最好的是这个
Date
----
29/05/17
29/05/17
Time
----
1227
1424
Terminal
--------
A999
A999
Enquirer
--------
CA75849
CA75849
Enquiry
-------
SEARCH REF NAME : DOE/JOHN CHAPTER CODE =
SEARCH REF NAME : SMITH/SIMON/PETER CHAPTER CODE =
提前感谢您的帮助!
这里的问题是在导出之前需要将对象转换为字符串。
要使您的代码正常工作,您可以稍微修改对象创建:
$csv = @()
for ($i = 0;$i -lt $Date.Length; $i++) {
$obj = New-Object -TypeName PSObject
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Date" -Value $Date[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Time" -Value $Time[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Terminal" -value $Terminal[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Enquirer" -value $Enquirer[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "Enquiry" -value $Enquiry[$i]
Add-Member -InputObject $obj -MemberType NoteProperty -Name "DOB" -value $DOB[$i]
$csv += $obj
}
解释:
这里的问题是你试图创建一个数组对象,而你应该创建一个对象数组。这就是为什么在导出时得到 System.Object[]
而不是预期值的原因。
注意:看看你粘贴在这里的代码和文件格式。这一行:
$TopLine = $XmlDocument | Select-String "A1"
应该是
$TopLine = $XmlDocument | Select-String "A999"
我使用了不同的方法,
- 将文件拆分为以虚线和 分隔的部分
- 3 个不同的正则表达式使用命名(捕获组)来 grep 每种线型的属性。
第一个在 RegEx101.com - 所有找到的属性都存储在一个中间 $Row 对象中,如果所有 RegEx 匹配则收集在
$Csv
## Q:\Test18\SO_51209341.ps1
$FileIn = '.\SO_51209341_data.txt'
$TodayCsv = '.\SO_51209341_data.csv'
$RE1 = [RegEx]'(?m)(?<Date>\d{2}\/\d{2}\/\d{2}) (?<Time>\d{4}) +(?<Terminal>A\d{3}) +(?<User>C[A-Z0-9]+) +(?<Enquirer>.*)$'
$RE2 = [RegEx]'\s+SEARCH REF\s+NAME : (?<Enquiry>.+?) (PAGE|CHAPTER) CODE ='
$RE3 = [RegEx]'\s+DATE OF BIRTH : (?<DOB>[0-9 /]+?/\d{4})'
$Sections = (Get-Content $FileIn -Raw) -split "={30,}`r?`n" -ne ''
$Csv = ForEach($Section in $Sections){
$Row= @{} | Select-Object Date,Time,Terminal,User,Enquirer,Enquiry,DOB
$Cnt = 0
If ($Section -match $RE1){++$Cnt
$Row.Date = $Matches.Date
$Row.Time = $Matches.Time
$Row.Terminal = $Matches.Terminal
$Row.User = $Matches.User
$Row.Enquirer = $Matches.Enquirer.Trim()
}
If ($Section -match $RE2){++$Cnt
$Row.Enquiry = $Matches.Enquiry
}
If ($Section -match $RE3){++$Cnt
$Row.DOB = $Matches.DOB
}
if ($Cnt -eq 3){$Row}
}
$csv | Format-Table
$csv | Export-Csv $Todaycsv -NoTypeInformation
示例输出修订版
> . Q:\Test18\SO_51209341.ps1
Date Time Terminal User Enquirer Enquiry DOB
---- ---- -------- ---- -------- ------- ---
29/05/17 1227 A999 CA75849 8875849 OCBA NCPS RBC/12/1960 DOE/JOHN / /1988
29/05/17 1424 A999 CA75849 8875849 OCBA NCPS RBC/60/2111 SMITH/SIMON/PETER / /1967