Ich habe mehrere Dateien mit dem gleichen Header und verschiedenen Vektoren darunter. Ich muss sie alle verketten, möchte aber, dass nur der Header der ersten Datei verkettet wird, und ich möchte nicht, dass andere Header verkettet werden, da sie alle gleich sind.
Zum Beispiel: file1.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
file2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
D
E
F
Ich brauche die Ausgabe zu sein
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F
Ich könnte ein Skript in R schreiben, aber ich brauche es in der Shell?
grep
(wie in der Antwort von sputnik ).head -n 10 file1.txt >output.txt && tail -q -n +11 file*.txt >>output.txt
(wenn Sie 10 Kopfzeilen haben). Wenn Ihre Dateien Nummern im Namen haben, achten Sie darauf, dassfile9.txt
diese zwischenfile89.txt
und sortiert sindfile90.txt
. Wenn Sie Ihre Dateien haben Zahlen mögenfile001.txt
, ...,files009.txt
,files010.txt
, ..., dannfiles*.txt
wird sie in der richtigen Reihenfolge aufzulisten.awk 'FNR==1 && NR!=1{next;}{print}' *.csv
Eine andere Lösung, ähnlich "
cat+grep
" von oben, verwendettail
undhead
:Schreiben Sie den Header der ersten Datei in die Ausgabe:
-
head -2
Erhält 2 erste Zeilen der Datei.Fügen Sie den Inhalt aller Dateien hinzu:
-
-n +3
machttail
Druckzeilen von 3 bis zum Ende,-q
weist es an, den Header mit dem Dateinamen nicht zu drucken (lesenman
),>>
fügt der Datei hinzu, überschreibt sie nicht als>
.Und sicher können Sie beide Befehle in eine Zeile setzen:
oder anstatt sie zur Erfolgskontrolle dazwischen zu
;
legen&&
.quelle
(head -2 file1.txt ; tail -n +3 -q file*.txt ) > all.txt
oder(head -2 file1.txt && tail -n +3 -q file*.txt ) > all.txt
Versuchen Sie Folgendes:
HINWEIS
-v
Flag bedeutet, die Übereinstimmung von grep umzukehren^
In REGEX bedeutet dies den Anfang der Zeichenfolge:
Es ist eine Bash- Array-Schneidetechnik.
quelle
<header>
Linien irgendwo in den Dateien, nicht nur am Anfang. Dies ist hier möglicherweise kein Problem, abhängig von den Daten.grep '^<header>' file1.txt >output.txt && grep -v '^<header>' file*.txt >>output.txt
Der
tail
Befehl (zumindest unter GNU) hat die Option, eine bestimmte Anzahl von Anfangszeilen zu überspringen. Gehen Sie wie folgt vor, um ab der zweiten Zeile zu drucken, dh einen einzeiligen Header zu überspringen:tail -n+2 myfile
So behalten Sie den zweizeiligen Header der ersten Datei in Bash bei, nicht jedoch den der zweiten:
Oder für viele Dateien:
Wenn bekannt ist, dass eine bestimmte Zeichenfolge in allen Kopfzeilen, jedoch niemals in den übrigen Eingabedateien vorhanden ist,
grep -v
ist dies ein einfacherer Ansatz, wie sputnik gezeigt hat.quelle
Kürzer (nicht unbedingt schneller) mit
sed
:Dadurch werden alle Zeilen gelöscht, die mit
<header>...
Zeile 3 beginnen, sodass der erste Header erhalten bleibt und die anderen Header entfernt werden. Wenn der Header eine andere Anzahl von Zeilen enthält, passen Sie den Befehl entsprechend an (z. B. für Header mit 6 Zeilen7
anstelle von3
).Wenn die Anzahl der Zeilen in der Kopfzeile unbekannt ist, können Sie Folgendes versuchen:
quelle
Angenommen, Sie verwenden einen Ordner mit TXT-Dateien mit demselben Header, der kombiniert / verkettet werden muss. In diesem Code werden alle TXT-Dateien in all.txt mit nur einem Header kombiniert . Die erste Zeile (durch Semikolon getrennte Zeilen) fasst alle zu verkettenden Textdateien zusammen, die zweite Zeile gibt den Header der ersten TXT-Datei in die Datei all.txt aus , und die letzte Zeile verkettet alle ohne den Header gesammelten Textdateien (durch Starten der Verkettung ab Zeile 2) und hängt es an all.txt an .
quelle