2010-10-25 11 views
57

Qual è il/modo più veloce più semplice per intercalare le linee di due (o più) file di testo? Esempio:Come interleave linee da due file di testo

File 1:

line1.1 
line1.2 
line1.3 

File 2:

line2.1 
line2.2 
line2.3 

Interleaved:

line1.1 
line2.1 
line1.2 
line2.2 
line1.3 
line2.3 

Certo è facile scrivere un piccolo script Perl che li apre entrambi e fa l'obiettivo. Ma mi stavo chiedendo se è possibile farla franca con meno codice, forse un one-liner usando gli strumenti Unix?

risposta

110
paste -d '\n' file1 file2 
+2

N.B. su alcune piattaforme "paste" è piuttosto limitato - ad es. su Solaris si può avere al massimo 12 file di input, e linee di uscita sono limitati a 511 caratteri. – user667489

-1
cat file1 file2 |sort -t. -k 2.1 

Ecco la sua precisato che il separatore è "" e che stiamo selezionando il primo carattere del secondo campo.

+0

Non capisco come funziona.Ad esempio, non ci sono due punti nell'input di tipo? Puoi spiegare di più? – Frank

+0

my bad, ha cambiato il ':' in '.' è solo il separatore, se non specificato sort usa blank per separare i campi. 'man sort' per maggiori informazioni. – Sujoy

+7

Questa risposta presuppone che l'input abbia effettivamente la forma letterale descritta nella domanda. Penso che avrebbe dovuto essere illustrativo. Sarebbe possibile trasformare ciascun file di input in questo modo, ma sarebbe molto più passa attraverso i dati. la risposta di codaddict è migliore. – Novelocrat

1

Ecco un modo GUI per farlo: incollarli in due colonne in un foglio di calcolo, copiare tutte le cellule, poi usare le espressioni regolari per sostituire le schede con a capo.

6

Ecco una soluzione che utilizza awk:

awk '{print; if(getline < "file2") print}' file1 

produce questo risultato:

line 1 from file1 
line 1 from file2 
line 2 from file1 
line 2 from file2 
...etc 

Utilizzando awk può essere utile se si desidera aggiungere un po 'di formattazione in più per l'uscita, per esempio se si desidera per etichettare ogni riga in base al file da cui proviene:

awk '{print "1: "$0; if(getline < "file2") print "2: "$0}' file1 

produce questo output:

1: line 1 from file1 
2: line 1 from file2 
1: line 2 from file1 
2: line 2 from file2 
...etc 

Nota: questo codice presuppone che file1 è maggiore o uguale lunghezza in file2.

Se file1 contiene più linee di file2 e vuoi mostrare righe vuote per file2 dopo che è terminata, aggiungere una clausola else alla prova getline:

awk '{print; if(getline < "file2") print; else print ""}' file1 

o

awk '{print "1: "$0; if(getline < "file2") print "2: "$0; else print"2: "}' file1 
1

@Sujoy's answer punti in una direzione utile. È possibile aggiungere numeri di riga, ordinare e spogliare i numeri di riga:

(cat -n file1 ; cat -n file2) | sort -n | cut -f2- 

Nota (di interesse per me) questo ha bisogno di un po 'di lavoro per ottenere l'ordine giusto, se invece di file statici si utilizza l'output dei comandi che può essere più lento o più veloce di un altro. In tal caso è necessario aggiungere/ordinare/rimuovere un altro tag oltre ai numeri di riga:

(cat -n <(command1...) | sed 's/^/1\t/' ; cat -n <(command2...) | sed 's/^/2\t/' ; cat -n <(command3) | sed 's/^/3\t/') \ 
    | sort -n | cut -f2- | sort -n | cut -f2- 
Problemi correlati