我有一个以下格式的文本文件:
.....
ENTRY,PartNumber1,,,
FIELD,IntCode,123456
...
FIELD,MFRPartNumber,ABC123,,,
...
FIELD,XPARTNUMBER,ABC123
...
FIELD,InternalPartNumber,3214567
...
ENTRY,PartNumber2,,,
...
...
...
表示这些字段之间还有其他数据。 ONLY 我可以确定的是,以ENTRY
开头的字段是一组新的记录。以FIELD
开头的行可以按任何顺序排列,并且并非所有行都可以存在于每组数据中。
InternalPartNumber
字段&返回那行数据。我还没有看到使用Get-Content
的方法,可以读取可变行数作为一组&能够搜索它。
这是我目前拥有的代码,它将读取一个文件,搜索一个字符串&用另一个替换它。我希望这可以修改为在这种情况下使用。
$ftype = "*.txt"
$fnames = gci -Path $filefolder1 -Filter $ftype -Recurse|% {$_.FullName}
$mfgPartlist = Import-Csv -Path "C:\test\mfrPartList.csv"
foreach ($file in $fnames) {
$contents = Get-Content -Path $file
foreach ($partnbr in $mfgPartlist) {
$oldString = $mfgPartlist.OldValue
$newString = $mfgPartlist.NewValue
if (Select-String -Path $file -SimpleMatch $oldString -Debug -Quiet) {
$stringData = $contents -imatch $oldString
$stringData = $stringData -replace "[\n\r]","|"
foreach ($dataline in $stringData) {
$file +"|"+$stringData+"|"+$oldString+"|"+$newString|Out-File "C:\test\Datachanges.txt" -Width 2000 -Append
}
$contents = $contents -replace $oldString $newString
Set-Content -Path $file -Value $contents
}
}
}
有没有办法阅读&使用Powershell在“块”中搜索文本文件?或者做一个预读&确定要搜索的内容?
答案 0 :(得分:1)
假设您的罚款不是太大而无法一次性读入内存:
$Text = Get-Content testfile.txt -Raw
($Text -split '(?ms)^(?=ENTRY)') |
foreach {
if ($_ -match '(?ms)^FIELD\S+ABC123')
{$_ -replace '(?ms).+(^Field\S+InternalPartNumber.+?$).+','$1'}
}
FIELD,InternalPartNumber,3214567
将整个文件作为单个多行字符串读取,然后在以' ENTRY'开头的任何行的开头拆分它。然后它测试包含' ABC123'的每个段的每个段,如果是,则删除除InternalPartNumber的FIELD行之外的所有内容。
答案 1 :(得分:0)
这不是我最好的工作,因为我刚从假期回来。你可以使用while循环读取文本并设置一个入口标志以吞噬文本块。但是,如果您的文件不是太大,那么您可以立即读取文本文件并使用正则表达式拆分块然后进行相应的处理。
$pattern = "ABC123"
$matchedRowToReturn = "InternalPartNumber"
$fileData = Get-Content "d:\temp\test.txt" | Where-Object{$_ -match '^(entry|field)'} | Out-String
$parts = $fileData | Select-String '(?smi)(^Entry).*?(?=^Entry|\Z)' -AllMatches | Select-Object -ExpandProperty Matches | Select-Object -ExpandProperty Value
$parts | Where-Object{$_ -match $pattern} | Select-String "$matchedRowToReturn.*$" | Select-Object -ExpandProperty Matches | Select-Object -ExpandProperty Value
这将在文本文件中读取,删除任何非入口或字段相关的行,作为一个长字符串并将其拆分为以工作开头的行开头"条目&# 34 ;.
然后我们放弃那些"部分"不包含$pattern
。剩下的那个匹配提取InternalPartNumber
行并出现。