从格式错误的 csv(在字段之间包含 LF 和 CR 字符)创建新的 csv
Creating a new csv from malformed csv (containing LF and CR characters in between a field)
我有一个 4 列的 csv 文件,其中一列分布在多行中,如下所示:
Number#,Scenes,OkOrFail,Time(ms)
1,com.mine[scenario->GRADE_1:thsi is test is request from Eol ],OK,3613
2,com.mine[scenario->GRADE_900:MSA Harvest all losses ],OK,1325
14,com.mine[scenario->GRADE_450:Great lamps Entity with xbars
Entity used SplitEnt
Model : silicon8],OK,930
15,com.mine[scenario->GRADE_985:request picking from the transmitter
Entity used silicon-B.E0004
],FAIL,728
16,com.mine[scenario->GRADE_120:single query from Receiver with
],OK,1245
要查看原始文件中不可打印的字符,请参见以下内容:
我希望在删除 Number# 列后从原始 csv 创建一个新的 csv,仅从 Scenes 列(GRADE_1、GRADE_900 等)中提取 GRADE_ 字符串并保留OkOrFail 列。
因此新的 csv 将如下所示:
Scenes,OkOrFail,Time(ms)
GRADE_1,OK,3613
GRADE_900,OK,1325
GRADE_450,OK,930
GRADE_985,FAIL,728
GRADE_120,OK,1245
我认为构建一个正则表达式来匹配整行并捕获我想要稍后输出的内容会起作用。这是我的正则表达式:
^[0-9]+,.+>([A-Z_0-9]+)[^,]+(,[A-Z]+.*)
现在,在 Notepad++ 中,这可以正常工作,但在实际的 powershell 中(使用 5.1 版)只有前两行可以正常工作。
这是我的代码:
$origstring = "^[0-9]+,.+>([A-Z_0-9]+)[^,]+(,[A-Z]+.*)"
$testNameOnly = ''
$statusAndDuration = ''
$csvfile = "C:\small_bad.csv"
(Get-Content $csvfile) | % {
$_ = $_ -replace "Number#,", ''
$_ = $_ -replace $origstring, ($testNameOnly + $statusAndDuration)
Write-Host $_
}
输出为:
PS C:\Windows\SysWOW64\WindowsPowerShell\v1.0>
Scenes,OkOrFail,Time(ms)
GRADE_1,OK,3613
GRADE_900,OK,1325
14,com.mine[scenario->GRADE_450:Great lamps Entity with xbars
Entity used SplitEnt
Model : silicon8],OK,930
15,com.mine[scenario->GRADE_985:request picking from the transmitter
Entity used silicon-B.E0004
],FAIL,728
16,com.mine[scenario->GRADE_120:single query from Receiver with
],OK,1245
正如 Wiktor Stribiżew 评论的那样,Get-Content
在换行符上拆分文件并输出单独的行,但是您需要正则表达式来匹配多行,因此它无法工作。 Get-Content -Raw
使其将整个文件读入一个字符串,包括换行符。
我的方法是匹配 com.mine[...]
文本并将其用双引号引起来,从而使数据成为 Import-Csv
可以处理的有效 CSV。
(Get-Content -Raw .\test.txt) -replace '(com\.mine\[[^\]]+\])', '""' |
ConvertFrom-Csv | Format-List
注意。假设无法将 ]
符号放入 com.mine[ data here ]
部分。
捕获文件的全部内容(而不是逐行方法)然后执行正则表达式魔术:
$x = get-content -raw -path Filename1 ; $x -replace $origstring, ($testNameOnly + $statusAndDuration) | set-content -path Filename2
我有一个 4 列的 csv 文件,其中一列分布在多行中,如下所示:
Number#,Scenes,OkOrFail,Time(ms)
1,com.mine[scenario->GRADE_1:thsi is test is request from Eol ],OK,3613
2,com.mine[scenario->GRADE_900:MSA Harvest all losses ],OK,1325
14,com.mine[scenario->GRADE_450:Great lamps Entity with xbars
Entity used SplitEnt
Model : silicon8],OK,930
15,com.mine[scenario->GRADE_985:request picking from the transmitter
Entity used silicon-B.E0004
],FAIL,728
16,com.mine[scenario->GRADE_120:single query from Receiver with
],OK,1245
要查看原始文件中不可打印的字符,请参见以下内容:
我希望在删除 Number# 列后从原始 csv 创建一个新的 csv,仅从 Scenes 列(GRADE_1、GRADE_900 等)中提取 GRADE_ 字符串并保留OkOrFail 列。
因此新的 csv 将如下所示:
Scenes,OkOrFail,Time(ms)
GRADE_1,OK,3613
GRADE_900,OK,1325
GRADE_450,OK,930
GRADE_985,FAIL,728
GRADE_120,OK,1245
我认为构建一个正则表达式来匹配整行并捕获我想要稍后输出的内容会起作用。这是我的正则表达式:
^[0-9]+,.+>([A-Z_0-9]+)[^,]+(,[A-Z]+.*)
现在,在 Notepad++ 中,这可以正常工作,但在实际的 powershell 中(使用 5.1 版)只有前两行可以正常工作。
这是我的代码:
$origstring = "^[0-9]+,.+>([A-Z_0-9]+)[^,]+(,[A-Z]+.*)"
$testNameOnly = ''
$statusAndDuration = ''
$csvfile = "C:\small_bad.csv"
(Get-Content $csvfile) | % {
$_ = $_ -replace "Number#,", ''
$_ = $_ -replace $origstring, ($testNameOnly + $statusAndDuration)
Write-Host $_
}
输出为:
PS C:\Windows\SysWOW64\WindowsPowerShell\v1.0>
Scenes,OkOrFail,Time(ms)
GRADE_1,OK,3613
GRADE_900,OK,1325
14,com.mine[scenario->GRADE_450:Great lamps Entity with xbars
Entity used SplitEnt
Model : silicon8],OK,930
15,com.mine[scenario->GRADE_985:request picking from the transmitter
Entity used silicon-B.E0004
],FAIL,728
16,com.mine[scenario->GRADE_120:single query from Receiver with
],OK,1245
正如 Wiktor Stribiżew 评论的那样,Get-Content
在换行符上拆分文件并输出单独的行,但是您需要正则表达式来匹配多行,因此它无法工作。 Get-Content -Raw
使其将整个文件读入一个字符串,包括换行符。
我的方法是匹配 com.mine[...]
文本并将其用双引号引起来,从而使数据成为 Import-Csv
可以处理的有效 CSV。
(Get-Content -Raw .\test.txt) -replace '(com\.mine\[[^\]]+\])', '""' |
ConvertFrom-Csv | Format-List
注意。假设无法将 ]
符号放入 com.mine[ data here ]
部分。
捕获文件的全部内容(而不是逐行方法)然后执行正则表达式魔术:
$x = get-content -raw -path Filename1 ; $x -replace $origstring, ($testNameOnly + $statusAndDuration) | set-content -path Filename2