是否有将打印指定文件的 EOL 字符的 Powershell 命令?

Is there a Powershell command that will print a specified file's EOL characters?

我在以下目录中有四个具有不同 EOL 字符的文本文件:

C:\沙盒1.txt、2.txt、3.txt、4.txt

我想编写一个 powershell 脚本,它将遍历目录中的所有文件并找到每个文件正在使用的 EOL 字符并将它们打印到名为 EOL.txt[=13 的新文件中=]

EOL.txt 的示例内容:

1.txt UNIX(LF)
2.txt WINDOWS(CRLF)
3.txt WINDOWS(CRLF)
4.txt UNIX(LF)

我知道要遍历文件我需要类似下面的东西,但我不确定如何读取文件 EOL:

Get-ChildItem "C:\Sandbox" -Filter *.txt | 
Foreach-Object {
}

Get-Content "C:\Sandbox\*"  -EOL | Out-File -FilePath "C:\Sandbox\EOL.txt"
##note that EOL is not a valid Get-Content command

尝试以下操作:

Get-ChildItem C:\Sandbox\*.txt -Exclude EOL.txt |
  Get-Content -Raw |
    ForEach-Object {
      $newlines = [regex]::Matches($_, '\r?\n').Value | Select-Object -Unique
      $newLineDescr = 
        switch ($newlines.Count) {
          0 { 'N/A' }
          2 { 'MIXED' }
          default { ('UNIX(LF)', 'WINDOWS(CRLF)')[$newlines -eq "`r`n"] }
        }
      # Construct and output a custom object for the file at hand.
      [pscustomobject] @{
        Path          = $_.PSChildName
        NewlineFormat = $newLineDescr
      }
    } # | Out-File ... to save to a file - see comments below.

上面的输出是这样的:

FileName NewlineFormat
-------- -------------
1.txt    UNIX(LF)
2.txt    WINDOWS(CRLF)
3.txt    N/A
4.txt    MIXED

N/A 表示 没有 换行符, MIXED 表示 both CRLF 和 LF 换行符现在。

您可以保存输出:

  • 直接按照上面显示的 for-display 格式,通过将 > 重定向或管道 (|) 附加到 Out-File,如您的问题.

  • 或者,使用更适合程序化处理的结构化文本格式,例如 CSV;例如。: Export-Csv -NoTypeInformation -Encoding utf8 C:\Sandbox\EOL.txt

注:

  • 缺少逐个或批量读取文本文件的原始字节,分析换行格式的唯一方法是完整读取文件 并搜索换行序列。 Get-Content -Raw 完整读取给定文件。

  • [regex]::Matches($_, '\r?\n').Value 从文件内容中提取所有换行序列——无论是 CRLF 还是 LF,然后 Select-Object -Unique 将它们缩减为 distinct序列。

  • ('UNIX(LF)', 'WINDOWS(CRLF)')[$newlines -eq "`r`n"] 是以下三元条件的一种方便但有点模糊的模拟:

    • $newlines -eq "`r`n" ? 'WINDOWS(CRLF)' : 'UNIX(LF)',可以在 PowerShell (Core) 7+ as-is 中使用,但不幸的是不受支持在 Windows PowerShell.

    • 该技术依赖于 [bool] 值在用作 数组索引 时强制转换为 [int] 值($true -> 1, $false -> 0), 从而从输入数组中选择合适的元素。

    • 如果您不介意冗长,可以使用常规 if 语句作为表达式(即,您可以将其输出直接分配给变量:$foo = if ...),适用于两个 PowerShell 版本:

      • if ($newlines -eq "`r`n") { 'WINDOWS(CRLF)' } else { 'UNIX(LF)' }

通过 WSL 的更简单替代方案,如果已安装:

WSL 附带 file 实用程序 ,它分析文件的内容并报告摘要信息,包括换行符格式。

虽然您无法控制输出格式,它总是包含附加信息,例如文件的字符编码,但命令要简单得多:

Set-Location C:\Sandbox
wsl file *.txt

注意事项:

  • 此方法基本上仅限于 本地 驱动器上的文件。
  • 如果切换到目标目录。不是一个选项,相对路径需要将它们的 \ 实例转换为 /,而 完整 路径需要驱动器规格。例如 C: 翻译成 /mnt/c(小写!)。

解释输出:

  • 如果术语 line terminators(指换行符)在输出(文本文件)中未提及,则仅隐含 Unix (LF) 换行符。
  • Windows (CRLF) 仅当您看到 with CRLF line terminators
  • 时才隐含换行符
  • 如果 混合 LF 和 CRLF,您将看到 with CRLF, LF line terminators
  • 如果没有换行符,您会看到 with no line terminators