6

问题说明了一切,我有一个 500,000 行的文件,它是作为 Windows 机器上自动构建过程的一部分生成的,并且充满了^M。当它出门时需要*nix友好,这里最好的方法是什么,是否有一个方便的代码片段可以为我做到这一点?还是我需要编写一个小 C# 或 Java 应用程序?

4

7 回答 7

11

这是一个 Perl 单行代码,取自http://www.technocage.com/~caskey/dos2unix/

#!/usr/bin/perl -pi
s/\r\n/\n/;

您可以按如下方式运行它:

perl dos2unix.pl < file.dos > file.unix

或者,您也可以以这种方式运行它(转换就地完成):

perl -pi dos2unix.pl file.dos

这是我的(天真的)C 版本:

#include <stdio.h>

int main(void)
{
   int c;
   while( (c = fgetc(stdin)) != EOF )
      if(c != '\r')
         fputc(c, stdout);
   return 0;
}

您应该使用输入和输出重定向运行它:

dos2unix.exe < file.dos > file.unix
于 2008-11-24T01:01:56.747 回答
6

如果安装一个基本的cygwin太繁重,网上有许多独立的dos2unixunix2dos基于 Windows 独立控制台的程序,其中许多都提供 C/C++ 源代码。如果我正确理解了需求,那么这些解决方案中的任何一个都可以很好地适合自动构建脚本。

于 2008-11-24T02:24:09.747 回答
5

如果您在 Windows 上并且需要在批处理脚本中运行某些东西,您可以编译一个简单的 C 程序来解决这个问题。

#include <stdio.h>

int main() {
    while(1) {
        int c = fgetc(stdin);

        if(c == EOF)
            break;

        if(c == '\r')
            continue;

        fputc(c, stdout);
    }

    return 0;
}

用法:

myprogram.exe < input > output

就地编辑会有点困难。此外,您可能出于某种原因想要保留原件的备份(例如,以防您不小心删除了二进制文件)。

该版本删除了所有CR 字符;如果您只想删除 CR-LF 对中的那些,您可以使用(这是经典的单字符返回方法 :-):

/* XXX Contains a bug -- see comments XXX */

#include <stdio.h>

int main() {
    int lastc = EOF;
    int c;
    while ((c = fgetc(stdin)) != EOF) {
        if ((lastc != '\r') || (c != '\n')) {
            fputc (lastc, stdout);
        }
        lastc = c;
    }
    fputc (lastc, stdout);
    return 0;
}

您可以使用模式“r+”就地编辑文件。下面是一个通用的 myd2u 程序,它接受文件名作为参数。注意:这个程序使用 ftruncate 在结尾处去掉多余的字符。如果有更好的(标准)方法可以做到这一点,请编辑或评论。谢谢!

#include <stdio.h>

int main(int argc, char **argv) {
    FILE *file;

    if(argc < 2) {
        fprintf(stderr, "Usage: myd2u <files>\n");
        return 1;
    }

    file = fopen(argv[1], "rb+");

    if(!file) {
        perror("");
        return 2;
    }

    long readPos = 0, writePos = 0;
    int lastC = EOF;

    while(1) {
        fseek(file, readPos, SEEK_SET);
        int c = fgetc(file);
        readPos = ftell(file);  /* For good measure. */

        if(c == EOF)
            break;

        if(c == '\n' && lastC == '\r') {
            /* Move back so we override the \r with the \n. */
            --writePos;
        }

        fseek(file, writePos, SEEK_SET);
        fputc(c, file);
        writePos = ftell(file);

        lastC = c;
    }

    ftruncate(fileno(file), writePos); /* Not in C89/C99/ANSI! */

    fclose(file);

    /* 'cus I'm too lazy to make a loop. */
    if(argc > 2)
        main(argc - 1, argv - 1);

    return 0;
}
于 2008-11-24T01:07:27.797 回答
4
tr -d '^M' < infile > outfile

您将输入 ^M 为: ctrl+V , Enter

编辑:您可以使用 '\r' 而不是手动输入回车,[感谢@strager ]

tr -d '\r' < infile > outfile

编辑 2 :'tr' 是一个 unix 实用程序,您可以从http://unxutils.sourceforge.net [感谢@Rob Kennedy ]下载本机 Windows 版本或使用cygwin的 unix 仿真。

于 2008-11-24T00:52:12.243 回答
1

将它从 dos 框 ftp 到 unix 框,作为 ascii 文件,而不是二进制文件。Ftp 将剥离crlf并插入lf。将其作为二进制文件传回dos box,lf会被保留。

于 2008-11-24T00:50:05.740 回答
1

一些文本编辑器,例如UltraEdit/UEStudio内置了这个功能。

File > Conversions > DOS to UNIX

于 2008-11-24T01:24:52.707 回答
-2

如果它只是一个文件,我使用记事本++。很好,因为它是免费的。我安装了 cygwin 并使用我为多个文件编写的一个衬里脚本。如果您对脚本感兴趣,请发表评论。(我现在没有它可用。)

于 2008-11-24T02:42:06.577 回答