在 Windows 中,对 500k 行文件执行 dos2unix 的最佳方法是什么?

发布于 2024-07-09 22:58:15 字数 186 浏览 7 评论 0原文

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

Question says it all, I've got a 500,000 line file that gets generated as part of an automated build process on a Windows box and it's riddled with ^M's. When it goes out the door it needs to *nix friendly, what's the best approach here, is there a handy snippet of code that could do this for me? Or do I need to write a little C# or Java app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

裸钻 2024-07-16 22:58:15

这是 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

Here is a Perl one-liner, taken from http://www.technocage.com/~caskey/dos2unix/

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

You can run it as follows:

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

Or, you can run it also in this way (the conversion is done in-place):

perl -pi dos2unix.pl file.dos

And here is my (naive) C version:

#include <stdio.h>

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

You should run it with input and output redirection:

dos2unix.exe < file.dos > file.unix
时常饿 2024-07-16 22:58:15

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

If installing a base cygwin is too heavy, there are a number of standalone dos2unix and unix2dos Windows standalone console-based programs on the net, many with C/C++ source available. If I'm understanding the requirement correctly, either of these solutions would fit nicely into an automated build script.

为你鎻心 2024-07-16 22:58:15

如果您使用的是 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;
}

If you're on Windows and need something run in a batch script, you can compile a simple C program to do the trick.

#include <stdio.h>

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

        if(c == EOF)
            break;

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

        fputc(c, stdout);
    }

    return 0;
}

Usage:

myprogram.exe < input > output

Editing in-place would be a bit more difficult. Besides, you may want to keep backups of the originals for some reason (in case you accidentally strip a binary file, for example).

That version removes all CR characters; if you only want to remove the ones that are in a CR-LF pair, you can use (this is the classic one-character-back method :-):

/* 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;
}

You can edit the file in-place using mode "r+". Below is a general myd2u program, which accepts file names as arguments. NOTE: This program uses ftruncate to chop off extra characters at the end. If there's any better (standard) way to do this, please edit or comment. Thanks!

#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;
}
晒暮凉 2024-07-16 22:58:15
tr -d '^M' < infile > outfile

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

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

tr -d '\r' < infile > outfile

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

tr -d '^M' < infile > outfile

You will type ^M as : ctrl+V , Enter

Edit: You can use '\r' instead of manually entering a carriage return, [thanks to @strager]

tr -d '\r' < infile > outfile

Edit 2: 'tr' is a unix utility, you can download a native windows version from http://unxutils.sourceforge.net[thanks to @Rob Kennedy] or use cygwin's unix emulation.

羁绊已千年 2024-07-16 22:58:15

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

Ftp it from the dos box, to the unix box, as an ascii file, instead of a binary file.
Ftp will strip the crlf, and insert a lf. Transfer it back to the dos box as a binary file, and the lf will be retained.

小糖芽 2024-07-16 22:58:15

某些文本编辑器(例如 UltraEdit/UEStudio)内置了此功能。

文件> 转换> DOS 到 UNIX

Some text editors, such as UltraEdit/UEStudio have this functionality built-in.

File > Conversions > DOS to UNIX

°如果伤别离去 2024-07-16 22:58:15

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

If it is just one file I use notepad++. Nice because it is free. I have cygwin installed and use a one liner script I wrote for multiple files. If your interest in the script leave a comment. (I don't have it available to me a this moment.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文