问题说明了一切,我有一个500,000行文件,它是在Windows机器上自动构建过程的一部分生成的,并且它充满了^ M的.当它出门时它需要*nix友好,这里最好的方法是什么,是否有一个方便的代码片段可以为我做这个?或者我是否需要编写一些C#或Java应用程序?
这是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版本:
#includeint main(void) { int c; while( (c = fgetc(stdin)) != EOF ) if(c != '\r') fputc(c, stdout); return 0; }
您应该使用输入和输出重定向来运行它:
dos2unix.exe < file.dos > file.unix
如果安装基础cygwin太重,网上有许多独立的dos2unix
和unix2dos
Windows独立的基于控制台的程序,其中许多都有C/C++源代码可用.如果我正确理解了这个要求,这些解决方案中的任何一个都可以很好地适应自动构建脚本.
如果你在Windows上并且需要在批处理脚本中运行某些东西,你可以编译一个简单的C程序来实现这一目的.
#includeint 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 */ #includeint 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在结尾处删除多余的字符.如果有更好的(标准)方法,请编辑或评论.谢谢!
#includeint main(int argc, char **argv) { FILE *file; if(argc < 2) { fprintf(stderr, "Usage: myd2u \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; }