从文件中间删除 CRLF

Remove CRLF from the middle of a file

我收到了一个文本文件,其中每行的长度应为 246 列。由于某种原因,文件中每 23,036 个字符后就会插入一个错误的 CRLF,从而导致各种问题。

文件格式为windows,所有行尾均为CRLF。

有没有什么方法可以从这个文件中删除这些额外的 CR-LF 字符,而不影响每行末尾存在的 CRLF?如果可能(awk、sed 等),Unix 工具将是此处的首选方法。

下面是添加额外的 CRLF 字符时文本块的外观示例。请注意,此文件的大小为 258 兆字节,额外的 CRLF 出现在文件下方不同位置的行中。

这是一个简单的 perl 脚本,它 运行 是一个循环,在每次迭代中,它将 23036 个字节复制到输出,然后跳过后面的 CRLF。

#!/usr/bin/perl
use strict;
use warnings;

while (1) {
    my $r=read STDIN,my $buf,23036;
    defined $r or die "error: $!";
    last if $r<23036;
    print $buf;
    my $c=read STDIN,my $crlf,2;
    defined $c or die "error: $!";
    $crlf eq "\r\n" or die "Not a CRLF";
}

你运行是这样的:

./myscript.pl < input-file.txt > output-file.txt

使用 awk

awk '
    length([=10=]) != 247 {sub(/\r$/,""); printf "%s", [=10=]; next} 
    {print}
' file

请注意 "unix" 文本文件有 \n 行结尾,因此 \r 只是一个普通字符。这就是为什么我使用 246+1 作为记录长度,并从记录片段中删除 CR。


更新:是的,上面的答案是不正确的:它不会正确地只追加下一行,而是追加接下来的两行。试试这个:

awk '
    length([=11=]) != 247 {sub(/\r$/,""); printf "%s", [=11=]; getline; print; next} 
    {print}
' file

当它检测到短行时,删除 CR 并在没有换行的情况下打印它。然后阅读下一行,我认为这是该记录的其余部分,并在 CR 完好无损的情况下打印它。然后继续下一条记录。

当你不确定在什么位置时,你可以删除所有行尾并在合适的位置添加它们:

(tr -d "\r\n" < my_inputfile | fold -w 245;echo) | sed 's/$/\r/'

需要 echo,因为 fold 不会在最后一行添加换行符。