我正在尝试从其他供应商提供的每个sqlcmd输出文件中删除底部的空白行。
$List=Get-ChildItem * -include *.csv
foreach($file in $List) {
$data = Get-Content $file
$name = $file.name
$length = $data.length -1
$data[$length] = $null
$data | Out-File $name -Encoding utf8
}
删除空行需要很长时间。有人知道更有效的方法吗?
使用Get-Content -Raw
将文件作为一个整体加载,作为单个字符串加载到内存中并对该字符串进行操作将为您带来最大的速度提升。
虽然这并不总是一个选项,具体取决于文件大小,但您提到了 sqlcmd 文件,可以假设它们足够小。
注意:
-
我所说的空行是指完全空或仅包含空格(换行符除外(的行。
-
修剪后的字符串在最后一行之后不会有一个最终的终止换行符,但是如果你把它传递给
Set-Content
(或Out-File
(,默认情况下会附加一个;使用-NoNewline
来抑制它,但不是特别是在类Unix平台上,即使是最后一行的文本文件也应该有一个尾随换行符。 -
除非另有说明,否则非空行上的尾随(或前导(空格在设计上不会被修剪。
-
这些解决方案使用
-replace
运算符,该运算符对正则表达式(正则表达式(进行操作。
删除所有尾随空白行:
注意:如果您确实只想删除最后一行(如果它恰好是空白的(,请参阅下面的倒数第二个解决方案。
(Get-Content -Raw $file) -replace 'r?ns*$'
在您的命令上下文中(略有修改(:
Get-ChildItem -Filter *.sqlcmd | ForEach-Object {
(Get-Content -Raw $_.FullName) -replace 'r?ns*$' |
Set-Content $_.FullName -Encoding utf8 -WhatIf # save back to same file
}
注意:上述命令中的-WhatIf
common参数可预览操作。一旦您确定操作将执行您想要的操作,请删除-WhatIf
。
如果从最后一个非空行中修剪尾随空格是可以接受/可取的,您可以更简单地编写:
(Get-Content -Raw $file).TrimEnd()
删除所有空白行,无论它们出现在文件中的哪个位置:
(Get-Content -Raw $file) -replace '(?m)As*r?n|r?ns*$'
这是一个概念上更简单的版本,它对Get-Content
输出的行数组进行操作,无需-Raw
(并且还返回一个数组(,但它的性能要差得多。
@(Get-Content $file) -notmatch '^s*$'
不要将其与Set-Content
/Out-Content
-NoNewline
结合使用,因为这将直接连接存储在数组元素中的行,它们之间没有换行符。如果没有-NoNewline
,你总是会在最后一行之后得到一个终止换行符。
如果最后一行为空,则仅删除该行:
(Get-Content -Raw $file) -replace 'r?n[ t]*Z'
注意:
[ t]
匹配空格和制表符,而s
通常匹配所有形式的 Unicode 空格,包括 ASCII 范围之外的空格。在这种情况下,文件末尾的可选尾随换行符(终止最后一行(不被视为空行 - 无论是否存在这样的换行符都没有区别。
无条件删除最后一行,无论它是否为空:
(Get-Content -Raw $file) -replace 'r?n[^n]*Z'
注意:
在这种情况下,文件末尾的可选尾随换行符(终止最后一行(不被视为空行 - 无论是否存在这样的换行符都没有区别。
如果要删除最后一个非空行,请使用
(Get-Content -Raw $file).TrimEnd() -replace 'r?n[^n]*Z'
尝试用这一行替换。 数组值$data中不会有空行。
$data = get-content $file.FullPath | Where-Object {$_.trim() -ne "" }