Ich habe zwei parallele Dateien mit der gleichen Anzahl von Zeilen in zwei Sprachen und plane, diese beiden Dateien zeilenweise mit dem Trennzeichen zusammenzuführen |||
. ZB sind die zwei Dateien wie folgt:
Datei A:
1Mo 1,1 I love you.
1Mo 1,2 I like you.
Hi 1,3 I am hungry.
Hi 1,4 I am foolish.
Datei B:
1Mo 1,1 Ich liebe dich.
1Mo 1,2 Ich mag dich.
Hi 1,3 Ich habe Durst.
Hi 1,4 Ich bin neu.
Die erwartete Ausgabe sieht folgendermaßen aus:
1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.
Ich habe den paste
Befehl wie folgt ausprobiert :
paste -d "|||" fileA fileB
Die zurückgegebene Ausgabe enthält jedoch nur eine Pipe, z.
1Mo 1,1 I love you. |1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. |1Mo 1,2 Ich mag dich.
Gibt es eine Möglichkeit, jedes Leitungspaar durch ein Tripe Pipe zu trennen |||
?
text-processing
sed
awk
Stirnrunzeln
quelle
quelle
paste -d '|||' fileA - - fileB < /dev/null
Antworten:
Mit POSIX einfügen :
paste
verkettet die entsprechenden Zeilen aller Eingabedateien. Hier haben wir sechs Dateien,fileA
vier Dummy-Dateien von Standard in-
, undfileB
.Die Liste der Begrenzer enthält ein Leerzeichen, drei Pipe und ein Leerzeichen in dieser Reihenfolge, das
paste
zirkulär verwendet wird .Für die erste Zeile werden sechs Dateien,
fileA
die mit der ersten Dummy-Datei verkettet werden (die dank des no-op: -Operators nichts ist ), erzeugtline1-fileA<space>
.Die erste Dummy-Datei wird durch eine Pipe mit der zweiten verkettet
line1-fileA |
, dann die zweite Dummy-Datei mit der dritten Dummy-Datei erzeugenline1-fileA ||
, die dritte Dummy-Datei mit der vierten Dummy-Datei erzeugenline1-fileA |||
.Und die vierte Dummy-Datei mit
fileB
, produzierenline1-fileA ||| line1-fileB
.Dieser Schritt wird für alle Zeilen wiederholt, um das erwartete Ergebnis zu erhalten.
Die Verwendung von
:|
ist für weniger tippen und vor allem in der interaktiven Shell. In einem Skript sollten Sie Folgendes verwenden:um zu verhindern, dass eine Subshell erzeugt wird.
quelle
:|
. clevere Alternative zu</dev/null
- - - -
, aber beim nächsten Mal können Sie sogar ein paar Zeilen zur Erklärung schreiben :):|paste -d '|' fileA - - fileB
gibt die korrektere Version ohne Leerzeichen an.Nun, das benutzt weder sed, awk noch grep, aber du kannst es ziemlich einfach in bash machen. Der Befehl lautet:
Das Problem beim Einfügen ist, dass das Trennzeichen ein einzelnes Zeichen ist. Sie können auch ein einzelnes Zeichen einfügen und es mit sed transformieren. Dies ist jedoch fehleranfällig, wenn das Zeichen bereits in der Eingabedatei enthalten ist.
quelle
IFS=
vor jedem verwendenread
. Sie können es leicht mit tunpaste
. Siehe meine Antwort und auch diese, um zu sehen, warum die Verwendung vonwhile
Schleifen in Shell-Skripten vermieden werden sollte .Eine awk (GNU) Version
Mit dem
getline
Befehl inawk
können Sie$0
(alle Variablen für Spalten) ab dem nächsten Eingabedatensatzgetline < "filename"
festlegen , wenn Sie den nächsten$0
aus der angegebenen Datei festlegen .Warum hat Ihr Versuch nicht wie erwartet funktioniert? Daraus können
man paste
wir lesenaber es nutzt die Begrenzungszeichen eines für jede Spalte .
Also
paste -d '|*|*' fileA fileB fileA fileB
gibt der Befehl mir Zeilen alsEine
sed
Lösung, die ich selbst dann vermeiden möchte, wenn sie Ihrem ursprünglichen Versuch nahe kommt, da sie das erhaltene Verhalten an Ihren ursprünglichen Zweck anpasst:Um zu vermeiden, dass Sie jedes Muster
|
durch das neue ersetzen|||
, aber davon ausgehen müssen, dass das Pipe-Symbol (|
) in Ihren Daten nicht vorhanden ist , müssen Sie sich mit Sonderfällen befassen und den Code komplexer gestalten, um Nebenwirkungen zu vermeiden.Eine Variante mit dem Here String [ 1 ] -Konstrukt
<<<
Sie setzen 5 Trennzeichen mit
-d ' ||| '
(Leerzeichen, |, |, |, Leerzeichen) und 4 Dummy-Dateien (- - - -
), die Daten aus der leeren Zeichenfolge übernehmen''
.Getestet auf GNU Awk 4.0.1, Paste (GNU Coreutils) 8.21 und Sed (GNU Sed) 4.2.2
quelle
sed
Beispiel hinzu, um (:-)) und mehr Kommentare zu vermeiden.Wenn Sie die Magie und das Drama kreisförmiger Trennzeichen und Dummy-Dateien vermeiden möchten, können Sie Ihr Trennzeichen einfach an eine Datei anhängen, bevor Sie sie einfügen:
gibt
quelle
Sie können es auch in Python auf diese Weise tun.
quelle