Sql Powershell脚本以查找行终止符?

Sql Powershell脚本以查找行终止符?,sql,powershell,Sql,Powershell,PowerShell是否可以将线路终止符视为 例如,\n和r`n和0x0a 当使用记事本++返回带有换行终止符的文本文件的最后一个字符时,PowerShell将最后一个字符返回为空,我希望它能够返回\n 我要做的是识别那些没有以行终止符结尾的文件,因为这些文件破坏了我的SQL批量插入 谢谢PowerShell可以看到线路终端。为了看到它们以您想要的方式显示,您必须制作该输出 $hash = @{10 = '\n'; 13 = '\r'} if ((Get-Content file.txt -Ra

PowerShell是否可以将线路终止符视为

例如,
\n
r`n
0x0a

当使用记事本++返回带有换行终止符的文本文件的最后一个字符时,PowerShell将最后一个字符返回为空,我希望它能够返回
\n

我要做的是识别那些没有以行终止符结尾的文件,因为这些文件破坏了我的SQL批量插入


谢谢

PowerShell可以看到线路终端。为了看到它们以您想要的方式显示,您必须制作该输出

$hash = @{10 = '\n'; 13 = '\r'}
if ((Get-Content file.txt -Raw) -match '(\r|\n)+\z') {
    ([int[]][char[]]$matches.0).foreach({$hash[$_]})
}
else {
    'No Terminators Found'
}
Get Content-Raw
将文件作为单个字符串读取<代码>\r与回车符匹配<代码>\n与换行符匹配
|
是一个正则表达式替代项(有效的OR)<代码>+匹配一个或多个上一个匹配项
\z
是字符串的结尾(在本例中是文件的结尾)

如果
-match
运算符返回true,
$matches
将自动包含匹配的字符。将其放入
if
语句可防止其
$true
\
$false
输出,并允许我们仅在匹配成功时检查
$matches
[char[]
将换行符转换为
System.char
的数组,这样我们就可以返回那些
char
对象的整数数组(
[int[]
)。使用数组可以更容易地使用
foreach()
方法并对每个字符运行代码。如果不进行数组转换,您将从匹配结果中获得由多个字符组成的单个字符串

哈希表只是以所需格式显示控制字符的一种方法。您可以使用
if
switch
语句来进行检查


默认情况下,
\n
\r
控制字符在PowerShell控制台中不可见。但它们的字节和十六进制表示形式是可见的。将字符转换为
[char]
,然后
[int]
将其字节表示形式显示为整数。见下文:

[int][char]"`r"
13
[int][char]"`n"
10
您还可以利用
格式化Hex
查看文件内容的十六进制表示形式

Get-Content file.txt -Raw | Format-Hex

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   6C 69 6E 65 31                                   line1
请注意,当文件没有结尾换行符时,结尾
0A
\n
)和
0D
\r
)是如何丢失的?与此相反,请参见下面带有换行符结尾的同一文件

Get-Content file.txt -Raw | Format-Hex

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   6C 69 6E 65 31 0D 0A                             line1..
通过检索其
bytes
属性,可以从
Format Hex
输出中获取所有字节,并注意最后的
10
13
字节

(Get-Content file.txt -Raw | Format-Hex).Bytes

108
105
110
101
49
13
10

您可以运行一个简单的测试,如

Get-ChildItem -Path 'D:\Test' -File | ForEach-Object {
    [PsCustomObject]@{
        FileName = $_.FullName
        EndsWithLineTerminator = ($_ | Get-Content -Raw) -match '(\r?\n)$'
    }
}
输出将如下所示:

FileName                EndsWithLineTerminator
--------                ----------------------
D:\Test\AnotherFile.txt                  False
D:\Test\JustAFile.txt                    False
D:\Test\LF.sql                            True
D:\Test\NoLF.txt                         False
D:\Test\Something.sql                    False
如果您只对具有特定扩展名(如
.sql
)的文件感兴趣,请将
-Filter'*.sql'
添加到Get-ChildItem cmdlet。 如果还希望检查子文件夹中的文件,请添加
-Recurse


如果您还想知道使用了什么终止符(CRLF、CR或LF,如果有),您可以将上述内容扩展到:

Get-ChildItem -Path 'D:\Test' -File -Recurse | ForEach-Object {
    $termTest   = ($_ | Get-Content -Raw) -match '(\r?\n)$'
    $terminator = if ($termTest) {
        switch ($matches[1]) {
            "`r`n" { 'CRLF'; break }  # Carriage Return + Line Feed
            "`n"   { 'LF'  ; break }  # Line Feed
            "`r"   { 'CR' }           # Carriage Return
        }
    }
    [PsCustomObject]@{
        FileName               = $_.FullName
        EndsWithLineTerminator = $termTest
        TerminatorUsed         = $terminator
    }
}
表现出

FileName                EndsWithLineTerminator TerminatorUsed
--------                ---------------------- --------------
D:\Test\AnotherFile.txt                  False               
D:\Test\JustAFile.txt                    False               
D:\Test\LF.sql                            True CRLF          
D:\Test\NoLF.txt                         False               
D:\Test\Something.sql                    False 

这取决于您读取文件的方式。如果您使用类似于
Get Content
的东西,您将获得作为管道元素的单独行,因此您将不会看到终止符——这是设计的。如果您使用
Get Content-Raw
,您将以一个大字符串的形式返回文件,然后您可以拆分/检查自己。非常有用。感谢您解释PS如何解释EOF字符。我完全忘记了使用-Hex开关。要获得一个比这个更简单的脚本来实现我想要的目标是很困难的。谢谢