2016-09-05 7 views
1

Ich habe eine Situation, wo ich jede vierte Zeile einer großen Datei mit der entsprechenden Zeile aus einer anderen Datei, beginnend bei Zeile 1 (so Zeile 1) ersetzen möchte , 5, 9 usw.).Ersetzen jeder 4. Zeile einer Datei durch die entsprechende Zeile in einer anderen Datei

Ich habe versucht mit sed aber kann nicht herausfinden, wie Sie jede vierte Zeile der zweiten Datei als Eingabe für die Substitution verwenden.

Bisher habe ich: "?"

sed '1~4 s/.*/?/' original-file.txt > output-file.txt 

Was kann ich anstelle der Verwendung um die Linien richtig zu ersetzen?

Jede Hilfe wird sehr geschätzt!

Antwort

3

Immer wenn ich etwas sehe, das mehr als ein einfaches Denken beinhaltet, entferne ich sed aus meinem Gehirn und versuche es mit awk. Wahrscheinlich bin ich auch awk -voreingenommen, aber ich denke, dass die Art und Weise speichert es Daten und hat Zugriff auf die Zeilennummern ist viel besser und einfacher zu verstehen, dass sed ist.

So lassen Sie uns the FNR==NR trick verwenden Sie eine Datei zu überprüfen und dann die andere:

awk 'FNR==NR {data[FNR]=$0; next} # store data from file 1 
    (FNR%4==1){     # in file 2, if line number is (4k + 1) 
     $0=data[FNR]    # replace with the same line from the 1st file 
    }1' file1 file2    # print the line 

Der Schlüssel hier ist aus der 1-Datei alle Daten zu speichern, in dem Array data[], mit dem Index jeder Zeile sein seine Zeilennummer.

Dann wird, wenn die Datei 2 zu lesen, wird eine Linie mit der entsprechenden Zeile der Datei ersetzt, wenn ihre Zahl 1 ein Vielfaches von 4.

Siehe ein Beispiel mit einer Sequenz von 100 bis 110 mit Zahlen von 1 ist, bis 10 verschachtelt:

$ awk 'FNR==NR {data[FNR]=$0; next} (FNR%4==1){$0=data[FNR]}1' <(seq 10) <(seq 100 110) 
1 
101 
102 
103 
5 
105 
106 
107 
9 
109 
110 
+0

fyi: OP-Formulierungen spiegeln nicht den 'sed' Befehl, der auf Linien 1,5, 9,13 usw. funktioniert – Sundeep

+1

Ah ja, ich werde dies in meine Frage bearbeiten. Danke für die Hilfe! – PokeUse

+1

@special danke für die Beobachtung. 'FNR% 4 == 1 'sollte machen. Mal sehen, mit was das OP aktualisiert wird. – fedorqui

0

Wenn Sie nichts dagegen haben perl verwenden, hier ist ein kleines Skript

#!/usr/bin/perl 

open my $fh1,'<','original-file.txt' or die; 
open my $fh2,'<','other-file.txt' or die; 
open my $out,'>','output-file.txt' or die; 
my $n=0; 
while (<$fh1>) { 
    my $s=<$fh2>; 
    print $out ($n++ % 4 == 0 ? $s : $_); 
} 

dies vermeiden werden die Daten in den Speicher zu laden und arbeiten somit in cons wichtige Erinnerung.

0

Dies könnte für Sie arbeiten (GNU sed):

sed '1~4!d' file2 | sed $'1~4{R/dev/stdin\n;d}' file1 > outFile 

Dies nutzt 2 Anrufungen von sed und Rohre das Ergebnis der ersten in die zweite mit dem Dateinamen /dev/stdin. Verwenden Sie auch Bases $'...', um einen Zeilenvorschub in den zweiten Aufruf einzufügen.

Verwandte Themen