我使用Get-Content将txt文件拉入数组,该文件使用_作为行继续标记,并且连续行的数量可以是从1到多的任何数字。所以文字可能看起来像这样......
Jrn.Directive "DocSymbol" _
, "[Commercial-Default.rte]"
Jrn.Directive "GlobalToProj" _
, "[Commercial-Default.rte]", "Floor Plan: Level 1" _
, 0.01041666666667 _
, 1.00000000000000, 0.00000000000000, 0.00000000000000 _
, 0.00000000000000, 1.00000000000000, 0.00000000000000 _
, 0.00000000000000, 0.00000000000000, 1.00000000000000 _
, 0.00000000000000, 0.00000000000000, 0.00000000000000
我想重新格式化没有换行,我想知道是否有一些超级优雅的方法,我没有看到?因为我认为前进的方式是$ array中的foreach $行,如果行EndsWith(" ")设置行索引的起始索引,则向前搜索直到一行没有EndsWith(" ")并设置一个结束索引,将这些位组合并写入临时数组,然后在主循环继续时跳过两个索引之间的差异读行。如果没有更详细的伪代码,这是有道理的。 在任何情况下,它看起来都很笨拙和不优雅,我想知道是否有更好的方法?
我最初的想法是Get-Content可能内置了一些内容,但看起来你可以定义的唯一分隔符是End of Line(默认为\ n)。
所以,基于安东尼的输入,并意识到我需要首先组合线,然后删除不相关的线(这可能是多行开头)我现在有了这个。
$target = 'Z:\Support\Px 3.0\RFO Benchmark\Journal Cleanup\journal.0010.txt'
$cleanFile = 'Z:\Support\Px 3.0\RFO Benchmark\Journal Cleanup\journal.0010.CLEAN.txt'
$sourceFile = Get-Content $target
$cleanData = @()
function Relavant {
[CmdletBinding()]
param (
[string]$line
)
$irrelevant = @('Jrn.Directive “Username"', 'Jrn.Directive "IdleTimeTaskSymbol"', 'Jrn.Directive "WindowSize"', 'Jrn.Size')
foreach ($item in $irrelevant) {
if ($line.StartsWith($item)) {
$relevant = $false
} else {
$relevant = $true
}
}
$relevant
}
$string = ''
$continue = $false
$tempData = $(foreach ($line in $tempData) {
if ($line -match '^[^,]') {
$string = ''
$continue = $true
}
if ($continue) {
$string += $line
}
if ($line.EndsWith('_')) {
$continue = $true
} else {
$continue = $false
$string -replace '\s?_'
}
})
# Remove comments & irrelevant lines and do basic formatting
foreach ($line in $tempData) {
$line = $line.Trim()
if (-not ($line.StartsWith("'"))) {
if (Relavant $line) {
$line = $line -replace " ,", ","
$line = $line -replace '\s+', ' '
$cleanData += $line
}
}
}
Add-Content $cleanFile "' Cleaned by PxJournalCleaner`n"
foreach ($line in $cleanData) {
Add-Content $cleanFile $line
}
它运作良好,但我怀疑如果没有别的办法,我会再次使用替代方法来实施教育因素。我也不确定我是否完全理解安东尼的方法正在发生什么,所以我显然还有一些需要做的事情。谢谢大家!
答案 0 :(得分:2)
你应该让正则表达式匹配更精确,但它对我有用
$file = gc 'C:\temp\new 1.txt'
$string = ''
$cont = $false
$result = $(foreach ($line in $file) {
if ($line -match '^[^,]') {
$string = ''
$cont = $true
}
if ($cont) {
$string += $line
}
if ($line.EndsWith('_')) {
$cont = $true
} else {
$cont = $false
$string -replace '\s?_'
}
})
$result
答案 1 :(得分:1)
你的方法似乎完全没问题,虽然我可能一次只做一行。
您可以执行以下操作:
# read the wrapped lines from file
$lines = Get-Content C:\yourfile.txt
# initialize an array with a single empty string + a cursor that we'll use to keep track of the last index
$unwrappedLines = ,""
$cursor = 0
# iterate over the input strings
foreach($line in $lines){
if($line.EndsWith(" _")){
# Line is to be continued, remove line continuation character and add the rest of the string to the current index in our new array
$unwrappedLines[$cursor] += $line.Substring(0,$line.Length - 2)
}
else
{
# Line is not to be continued, add value as-is to current index
$unwrappedLines[$cursor] += $line
# Then increment our index cursor and initalize the next string in the array
$unwrappedLines[++$cursor] = ""
}
}
答案 2 :(得分:0)
如果文件足够小,只需将其作为一个字符串读取,并将所有_newlines替换为空。
(Get-Content -Raw "c:\temp\test.txt") -replace "_`r`n"
-Raw
适用于3.0。如果你没有那么Out-String
来救援。
(Get-Content "c:\temp\test.txt" | Out-String) -replace "_`r`n"
只需要找到一个后跟新行的下划线并删除它。