Ich habe eine große Datendatei und möchte sie basierend auf den Werten in Spalte 1 in kleinere Dateien aufteilen. Spalte 1 enthält beispielsweise zehnmal die Zahlen 1 bis 10, um 100 Zeilen zu ergeben, und ich möchte alle Zeilen mit den Zahlen „1“ oder „2“ oder „3“ usw. in einer eigenen Datei haben (vorzugsweise ohne Sortierung). Außerdem möchte ich den Befehl nicht 10 Mal ausführen, sondern ihn in einer Schleife ausführen.
Meine Dateien sehen folgendermaßen aus:
Der Befehl, den ich ausprobiert habe:
cat ID.txt | while read line; do awk '$1 == ${line}' test.txt >$line.txt;done
Zusammenfassend möchte ich, dass der Wert aus der Datei ID.txt gelesen wird, z. B. „1“, und dann alle Zeilen mit „1“ in der ersten Zeile extrahiert und in eine Datei mit dem Namen 1.txt eingefügt werden. Anschließend iteriert es zu 2, dann 3, dann 4 usw.
Aber irgendwie funktioniert der Teil '$1 == ${line}' nicht, glaube ich
Antwort1
Sie suchen nach einer -v
Möglichkeit awk
:
-v var=val
--assign var=val
Assign the value val to the variable var, before execution of
the program begins. Such variable values are available to the
BEGIN rule of an AWK program.
Etwas wie das:
cat ID.txt |
while read line; do awk -vline="$line" '$1 == l' test.txt >"$line".txt;done
Besser ließe es sich so ausdrücken (unter Vermeidung der sinnlosen Verwendung von „cat“):
while read line; do
awk -vline="$line" '$1 == l' test.txt >"$line".txt;
done < ID.txt
Dies ist jedoch sehr langsam und ineffizient. Sie führen den awk
Befehl test.txt
für jede Zeile von vollständig ID.txt
aus. Warum nicht einfach selbst einlesen ID.txt
und awk
die passenden Zeilen drucken:
awk 'NR==FNR{a[$1]++; next} ($1 in a){print >> $1".txt"}' ID.txt test.txt
Das Obige speichert das 1. Feld von ID.txt
im Array a
. NR
und FNR
sind spezielle awk
Variablen, die „die aktuelle Zeile des Eingabestroms“ und „die aktuelle Zeile der aktuellen Datei“ bedeuten. Die beiden sind nur dann gleich, wenn die erste Datei gelesen wird. Daher NR==FNR{a[$1]++; next}
wird nur für die Zeilen der ersten Datei ausgeführt. Der zweite Teil wird nicht ausgeführt, da next
angibt awk
, zur nächsten Zeile zu springen.
Der zweite Teil prüft, ob das erste Feld der aktuellen Zeile (denken Sie daran, dass dies nur für die zweite Datei ausgeführt wird) im Array vorhanden ist a
(was bedeutet, dass es in war ID.txt
) und druckt die Zeile, wenn dies der Fall ist, in eine Datei namens „field1.txt“.