powershell - 用于将多行文本提取到单行的 Powershell 脚本
问题描述
我需要通过 powershell 从文本文件中提取一些文本行到基于某些标准的新输出文件中,然后还将下一行的一些数据提取到同一行中。
这是文本文件的示例:
0 CARDHOLDER NUMBER TOKEN NUMBER MESSAGE DATE/TIME ACTIVITY REASON NTWK PAN EXP TRAN ID
0 1234567890123456 4234567890123456 11/12/14 15:34:38 T1-TKN CREATE VSN 49/12 314316099993286
TOKEN DATA: EXP DATE: 16/05 REQUESTOR ID: 45432112345 TYPE: T0 STATUS: I ASSURANCE LEVEL: 16 REQUEST METHOD: 6
TOKEN REF ID: TOKENREFERENCEDATAID012345678901 PAN REF ID: PANREFERENCEID
TERMS: VERSION: Terms and condition verification data DATE/TIME: Mon, 07 Apr 2014 10:25:217
TEXT MESSAGE: $TM*TOKEN NOTIFICATION ADVICE
0 5678901234561234 4234567890123456 11/12/14 15:34:44 T2-TKN DEACTIVATE VSN 49/12 314316100043288
TOKEN DATA: EXP DATE: 16/05 REQUESTOR ID: 45432112345 TYPE: T0 STATUS: I ASSURANCE LEVEL: 16 REQUEST METHOD: 6
TOKEN REF ID: TOKENREFERENCEDATAID012345678901 PAN REF ID: PANREFERENCEID
TERMS: VERSION: Terms and condition verification data DATE/TIME: Mon, 07 Apr 2014 10:25:217
TEXT MESSAGE: $TM*TOKEN NOTIFICATION ADVICE
所需的输出会将持卡人编号和请求者 ID 放在一行中,例如:
1234567890123456,45432112345
5678901234561234,45432112345
现在我有以下代码,但它不会从下一行提取子字符串,而是与卡号对齐:
$report = get-content $inputFile
foreach ($line in $report) {
if ($line -match 'T5-DEVICE PRV RSLT') {
$card = $line.Substring(2,16)
$lineRequestor = $line + 1
$requestorID = $lineRequestor.SubString(49,11)
if ($card.StartsWith("4")) {
$card = $card + ','
$output = $card + $requestorID
$output | out-file -FilePath $outputFile -Append
}
}
}
解决方案
以下基于简化Select-String
的解决方案通过它们包含的位数(分别为16
和)识别要提取的两条数据。11
# Search for lines with cardholder numbers and include one line below
# (-Context 0, 1)
Select-String '\b\d{16}\b' $inputFile -Context 0,1 | ForEach-Object {
# Match the requestor ID on the line below.
$null = $_.Context.PostContext[0] -match '\b\d{11}\b';
# Output the cardholder number found by Select-String and the
# requestor ID found with -match
$_.Matches[0].Value + ',' + $Matches[0]
} # | Set-Content $outputFile
删除#
以保存到$outputFile
。
使用您的示例输入文件,这会产生:
1234567890123456,45432112345
5678901234561234,45432112345
至于你尝试了什么:
$lineRequestor = $line + 1
这不是获取下一个输入行,而是与当前行执行字符串连接并附'1'
加到它。
通常,您不能(轻松)在foreach
循环执行的枚举中向前跳过。[1]
如果您想这样做,请使用带有indicesfor
的循环,如下面的简化示例所示:
$lines = 'one', 'two', 'three', 'four'
for ($i = 0; $i -lt $lines.Count; ++$i) {
# Output a pair of lines.
"item + next item: " + $lines[$i] + ', ' + $lines[++$i]
}
[1] 从技术上讲,你可以,但解决方案是模糊的,通过自动$foreach
变量:
foreach ($line in 'one', 'two', 'three', 'four') { $null = $foreach.MoveNext(); $nextLine = $foreach.Current; "$line - $nextLine" }
推荐阅读
- sql - 使用 table1 更新 table2 中的值
- php - 如何基于具有多个孩子的数组创建路径
- bash - 如何使用 exec 执行任意查找命令
- blogger - 在博客上的指定标签上显示小部件
- python - 将高分保存在游戏的文本文件中
- javascript - 如何将 RxPy 数据流发送到前端 javascript
- jenkins - 作业结果是 Post Script 结果
- javascript - 创建一个函数,以 500 平方英尺的增量将基价提高 10%
- python - Django 不与 sqlite3 同步(官方投票教程)
- google-app-engine - Safari 'origin is not allowed' 阻止 AppEngine 身份感知代理 https://accounts.google.com/o/oauth2/v2/auth