使用Perl进行Windows和Unix文件行结束转换的终极指南

大多数程序员都知道,Windows和基于Unix的系统使用的文件行结束符不同。Windows使用CRLF,而基于Unix的系统使用LF。所以,在Perl中修复这个问题只需要一个简单的替换正则表达式,对吧?等等……

要求

您必须使用Perl 5.14或更高版本。

基于Unix系统的转换

这很简单。要将文件转换为Unix风格的行结束符(如Linux、BSD、OSX所使用的),只需打开终端并运行

perl -pi.bak -e 's/\R/\012/' /path/to/file

此代码通过将任何换行符字符(”\R”)替换为单个换行符字符(”\012”)来实现。从Perl 5.10版本开始,可用的“\R”元字符很有用,因为它甚至可以用于具有混合行结束风格的文件。使用内部切换(“i”)创建原始文件的备份,扩展名为“.bak”。要将文件从Unix转换为Windows风格的行结束符,使用以下代码

perl -pi.bak -e 's/\R/\015\012/' /path/to/file

此代码将任何垂直字符替换为Windows使用的CRLF(”\015\012”)行结束符。同样,这也可以用于具有Unix和Windows行结束符混合的文件。

Windows上的转换

在Windows上情况复杂一些;有一些需要注意的事项

  • 默认情况下,Perl将“\n”的值更改为CRLF。这意味着正则表达式匹配:“/\015\012/”在Windows上会失败,因为Perl实际上运行的是:“/\015\015\012/”。使用元字符和十六进制代码(”/\r\n/”和“/\x0d\x0a/”)的正则表达式也会因为相同的原因而失败。
  • 必须将单引号替换为双引号,以将代码包含在“e”中,并且在代码中需要单引号时必须使用引号操作符(例如“q||”)
  • 内部切换(“i”)可以正常工作,但任何扩展名(例如“.bak”)都会更改文件扩展名和与其关联的默认程序。下面的示例使用替代方法。

如果您正在使用cmd.exe或PowerShell,以下Perl单行将转换文件为Windows风格的行结束符

perl -pe "binmode(STDOUT);s/\R/\015\012/" /path/to/file > /path/to/new/file

这里的主要区别是:将单引号替换为双引号,“binmode(STDOUT)”关闭Perl的CRLF行结束符,并使用重定向“>”将内容写入不同的文件,而不是使用内部切换。要使用cmd.exe将文件转换为Unix风格的行结束符,这将有效

perl -pe "binmode(STDOUT);s/\R/\012/" /path/to/file > /path/to/new/file

在PowerShell中需要一些更多的更改。要将转换为Unix风格的行结束符,使用以下代码

perl -ne "open(OUT, q(>), q(/path/to/new/file));binmode(OUT);print OUT s/\R/\012/r" /path/to/file

那么刚才发生了什么?首先,我们将命令行切换“p”更改为“n”。这阻止Perl将每行处理结果打印到标准输出。相反,我们打开了一个追加文件句柄“OUT”到我们的输出文件,并自己打印结果。我们必须这样做的原因是PowerShell自动将标准输出解释为Unicode,并将Unix风格的行结束符替换为Windows CRLF行结束符。因此,使用重定向方法(”>”)不起作用。而且,在你尝试之前,像这样管道输出会生成错误

# Don't do this!
perl -pe "binmode(STDOUT);s/\R/\012/r" /path/to/file | set-content /path/to/new/file -Encoding Byte

我们还必须使用引号操作符(“q()”)引用我们的内容,而不是使用单引号。最后,替换正则表达式(“s/\R/\012/“)被更改为使用“r”修饰符,它返回替换的结果而不修改原始变量。这个功能从Perl 5.14版本开始可用。

进一步阅读

Perl的官方文档“perlrun”条目有很多关于Perl命令行开关的细节。您可以在网上或通过在命令行中输入“perldoc perlrun”来访问它。

彼得里斯·克鲁明斯(Peteris Krummins)的网站提供了大量的Perl单行脚本。他的新书《Perl单行脚本:130个实用的脚本》(Perl One-Liners: 130 Programs That Get Things Done)刚刚出版(推广链接)。书中包含了许多有用的单行脚本,还提供了9页关于在Windows上运行单行脚本的详细指导——强烈推荐!


本文最初发表在PerlTricks.com

标签

大卫·费尔兰(David Farrell)

大卫是一名专业程序员,他经常在Twitter博客上分享关于代码和编程艺术的文章。

浏览他们的文章

反馈

这篇文章有什么问题吗?请在GitHub上打开一个问题或提交一个拉取请求以帮助我们。