Qual è il modo migliore di fare dos2unix su un file di linea da 500k, in Windows? [chiuso]

StackOverflow https://stackoverflow.com/questions/313178

  •  10-07-2019
  •  | 
  •  

Domanda

La domanda dice tutto, ho un file di 500.000 righe che viene generato come parte di un processo di compilazione automatizzato su una finestra di Windows ed è pieno di ^ M . Quando esce dalla porta ha bisogno di * nix amichevole, qual è l'approccio migliore qui, c'è un utile frammento di codice che potrebbe fare questo per me? O devo scrivere una piccola app C # o Java?

È stato utile?

Soluzione

Ecco un one-liner Perl, tratto da http://www.technocage.com / ~ Caskey / dos2unix /

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

Puoi eseguirlo come segue:

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

Oppure puoi eseguirlo anche in questo modo (la conversione viene eseguita sul posto):

perl -pi dos2unix.pl file.dos

Ed ecco la mia (ingenua) versione C:

#include <stdio.h>

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

Dovresti eseguirlo con il reindirizzamento di input e output:

dos2unix.exe < file.dos > file.unix

Altri suggerimenti

Se l'installazione di una base cygwin è troppo pesante, ci sono un certo numero di stand2un2 e unix2dos programmi basati su console standalone di Windows in rete, molti con sorgente C / C ++ disponibile. Se capisco correttamente il requisito, una di queste soluzioni si adatterebbe perfettamente a uno script di build automatizzato.

Se sei su Windows e hai bisogno di eseguire qualcosa in uno script batch, puoi compilare un semplice programma C per fare il trucco.

#include <stdio.h>

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

        if(c == EOF)
            break;

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

        fputc(c, stdout);
    }

    return 0;
}

Utilizzo:

myprogram.exe < input > output

La modifica sul posto sarebbe un po 'più difficile. Inoltre, potresti voler conservare i backup degli originali per qualche motivo (ad esempio, nel caso in cui accidentalmente rimuovi un file binario).

Quella versione rimuove tutti caratteri CR; se vuoi rimuovere solo quelli che si trovano in una coppia CR-LF, puoi usare (questo è il classico metodo con un carattere indietro :-):

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

Puoi modificare il file sul posto utilizzando la modalità " r + " ;. Di seguito è riportato un programma generale myd2u, che accetta nomi di file come argomenti. NOTA: questo programma utilizza ftruncate per tagliare caratteri extra alla fine. Se esiste un modo migliore (standard) per farlo, modifica o commenta. Grazie!

#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;
}
tr -d '^M' < infile > outfile

Digiterai ^ M come: ctrl + V, Invio

Modifica : puoi usare '\ r' invece di inserire manualmente un ritorno a capo, [ grazie a @strager ]

tr -d '\r' < infile > outfile

Modifica 2 : 'tr' è un'utilità unix, puoi scaricare una versione nativa di Windows da http://unxutils.sourceforge.net [ grazie a @Rob Kennedy ] o usa emulazione unix di cygwin .

Ftp dalla casella dos, alla casella unix, come file ASCII, anziché come file binario. Ftp rimuoverà il crlf e inserirà un lf . Riportalo nella casella dos come file binario e lf verrà conservato.

Alcuni editor di testo, come UltraEdit / UEStudio hanno questa funzionalità integrata.

File > Conversioni > Da DOS a UNIX

Se è solo un file uso notepad ++. Bello perché è gratuito. Ho installato Cygwin e utilizzo uno script di una riga che ho scritto per più file. Se il tuo interesse per la sceneggiatura lascia un commento. (Non ce l'ho a disposizione in questo momento.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top