2008-11-24 77 views
6

Câu hỏi nói tất cả, tôi có một tệp 500.000 dòng được tạo ra như là một phần của quá trình xây dựng tự động trên hộp Windows và nó bị thủng với ^M. Khi nó ra khỏi cửa, cần phải * nix thân thiện, cách tiếp cận tốt nhất ở đây là có đoạn mã tiện dụng nào có thể làm điều này cho tôi không? Hay tôi cần viết một ứng dụng C# hay Java nhỏ?Cách tốt nhất để làm dos2unix trên một tệp dòng 500k, trong Windows là gì?

Trả lời

9

Dưới đây là một Perl one-liner, lấy từ http://www.technocage.com/~caskey/dos2unix/

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

Bạn có thể chạy nó như sau:

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

Hoặc, bạn có thể chạy nó cũng theo cách này (việc chuyển đổi là thực hiện tại chỗ):

perl -pi dos2unix.pl file.dos 

Và đây là (ngây thơ phiên bản C) của tôi:

012.
#include <stdio.h> 

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

Bạn nên chạy nó với đầu vào và đầu ra chuyển hướng:

dos2unix.exe <file.dos> file.unix 
+0

Đừng lo lắng về hiệu suất cho đến khi bạn phải đối phó với terabyte: D Phiên bản C mất ~ 5 giây để chuyển đổi một tệp 65 MB với 500.000 dòng văn bản (trên Pentium4 cũ với đĩa EIDE chuẩn) –

+0

@Federico, đó (ngây thơ) Phiên bản C sẽ loại bỏ tất cả các ký tự CR, không chỉ những ký tự trong một cặp CR-LF. Nhưng tôi đoán đó là lý do tại sao bạn gọi nó là ngây thơ. :-) – paxdiablo

+0

@Pax: chính xác: D –

1

Ftp từ hộp dos, vào hộp unix, dưới dạng tệp ascii, thay vì tệp nhị phân. Ftp sẽ xóa crlf và chèn lf. Chuyển nó trở lại hộp dos dưới dạng tệp nhị phân và lf sẽ được giữ lại.

+0

Tôi không phải là một fan hâm mộ của điều này, có vẻ như nó sẽ là một PITA như là một phần của một xây dựng tự động. Plus, nếu tôi không có một hộp unix địa phương trên mạng, tôi đã hoặc là phải mua một, hoặc chuyển các tập tin qua mạng WAN, hai lần. Phải làm được điều này một cách cục bộ, phải không? – ninesided

+0

Không phải I. Tôi yêu cầu ít nhất một máy chủ FTP đang hoạt động, quá mức cần thiết để chuyển đổi tệp. –

+0

Câu trả lời hay để cười! –

4
tr -d '^M' <infile> outfile 

Bạn sẽ gõ^M như: Ctrl + V, Nhập

Sửa: Bạn có thể sử dụng '\ r' thay vì phải nhập một trở về vận chuyển, [nhờ @strager]

tr -d '\r' <infile> outfile 

Sửa 2: 'tr' là một tiện ích unix, bạn có thể tải về một phiên bản cửa sổ có nguồn gốc từ http://unxutils.sourceforge.net [thứ anks để @Rob Kennedy] hoặc sử dụng mô phỏng unix cygwin.

+0

Điều này làm việc tốt đẹp nếu bạn có tr trên hộp dos. Quá nhanh. – EvilTeach

+0

cygwin có thể được giúp đỡ – hayalci

+0

Tôi không có tr, nơi tôi có thể tìm thấy nó? – ninesided

5

Nếu bạn đang ở trên Windows và cần một cái gì đó chạy trong một kịch bản hàng loạt, bạn có thể biên dịch một chương trình C đơn giản để làm các 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; 
} 

Cách sử dụng:

myprogram.exe <input> output 

Editing tại chỗ sẽ khó khăn hơn một chút. Bên cạnh đó, bạn có thể muốn giữ bản sao lưu của bản gốc vì lý do nào đó (trong trường hợp bạn vô tình loại bỏ một tập tin nhị phân, ví dụ).

Phiên bản đó xóa tất cả ký tự CR; nếu bạn chỉ muốn loại bỏ những người mà đang ở trong một cặp CR-LF, bạn có thể sử dụng (đây là cổ điển một nhân vật lại phương pháp :-):

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

Bạn có thể chỉnh sửa các tập tin tại chỗ sử dụng chế độ "r +". Dưới đây là một chương trình myd2u chung, chấp nhận tên tệp làm đối số. LƯU Ý: Chương trình này sử dụng ftruncate để cắt các ký tự thừa ở cuối. Nếu có cách nào tốt hơn (tiêu chuẩn) để thực hiện việc này, vui lòng chỉnh sửa hoặc nhận xét. Cảm ơn!

#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; 
} 
+0

@strager, được cố định để sử dụng int (yêu cầu cho EOF) và thêm mã để chỉ thực hiện CR trong một cặp CR-LF - hy vọng điều này sẽ giúp bạn có thêm đại diện. Oh có, và upvoted. – paxdiablo

+0

Tôi nhận thấy sự hiệu chỉnh bằng int; cảm ơn! Tôi sẽ để người thứ hai một mình, cho dù đó không phải là phong cách của tôi. =] – strager

+0

Đoạn mã thứ hai không thành công trên tệp trống, mặc dù nó khá tầm thường để sửa lỗi đó. –

1

Một số trình chỉnh sửa văn bản, chẳng hạn như UltraEdit/UEStudio có chức năng này được tích hợp sẵn.

File > Conversions > DOS to UNIX

+0

gVim cũng có thể thực hiện việc này, tải nó tự động trong chế độ DOS, sau đó nhập ": set filemode = unix" không có dấu ngoặc kép (từ bộ nhớ) và lưu. – paxdiablo

+0

không hữu ích cho quá trình tự động ... – ninesided

+0

ah, đúng. UEStudio thực sự có một kịch bản khá tốt và hệ thống macro được tích hợp sẵn, điều này thực sự cho phép bạn thực hiện điều này thông qua dòng lệnh, nhưng bạn nói đúng, nó không phải là công cụ tốt nhất cho quá trình tự động. – nickf

5

Nếu cài đặt một cơ sở cygwin là quá nặng, có một số chương trình giao diện điều khiển dựa trên dos2unixunix2dos của Windows độc lập độc lập trên mạng, nhiều với C++ nguồn/C có sẵn. Nếu tôi hiểu đúng yêu cầu, một trong hai giải pháp này sẽ phù hợp với kịch bản xây dựng tự động.

-2

Nếu đó chỉ là một tệp tôi sử dụng notepad ++. Đẹp vì nó miễn phí. Tôi đã cài đặt Cygwin và sử dụng một kịch bản một dòng tôi đã viết cho nhiều tập tin. Nếu bạn quan tâm đến kịch bản để lại một bình luận. (Tôi không có nó có sẵn cho tôi một thời điểm này.)

Các vấn đề liên quan