Ich habe eine ziemlich große CSV-Datei (75 MB). Ich versuche nur, ein Diagramm davon zu erstellen, daher brauche ich wirklich nicht alle Daten.
Umformulierung: Ich möchte n Zeilen löschen, dann eine Zeile behalten, dann n Zeilen löschen und so weiter.
Also, wenn die Datei so aussah:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
und n = 2, dann wäre die Ausgabe:
Line 3
Line 6
Es scheint, als sed
könnte dies möglich sein, aber ich konnte nicht herausfinden, wie. Ein Bash-Befehl wäre ideal, aber ich bin offen für jede Lösung.
Antworten:
NR
Die Variable (Anzahl der Datensätze) gibt die Anzahl der Datensätze an, da das Standardverhalten die neue Zeile fürRS
(Datensatztrenner) ist. Muster und Aktion sind im Standardformat von awk optional'pattern {actions}'
. Wenn wir nur einen Musterteilawk
angeben, werden alle Felder$0
für dietrue
Bedingungen unseres Musters geschrieben .quelle
awk 'NR == 1 || NR % 3 == 0'
awk 'NR == 1 || NR % 2 == 0' myfile.txt | wc -l
einer ungeraden Zahl bestätigt, während die ursprüngliche Datei eine gerade Anzahl von Zeilen hatte. @kev Antwort funktioniert am besten in meinem Testfall.sed
kann das auch machen:man sed
erklärt~
als:quelle
1p
druckt die erste Zeile,0~3p
druckt jede dritte Zeile ab Zeile 3 (dies1p
ist also erforderlich, um Zeile 1 zu drucken). Beachten Sie jedoch, dass dies0~3
nicht der Standard ist, sondern eine GNU sed-Erweiterung.sed -n '1p;0~10p' '.\in.txt' > out.txt
um die verkleinerte Datei in eine Ausgabedatei zu drucken.Perl kann das auch:
Dieses Programm gibt die erste Zeile seiner Eingabe und danach jede dritte Zeile aus.
Um es ein bisschen zu erklären,
<>
ist der Zeileneingabeoperator, der über die Eingabezeilen iteriert, wenn er in einerwhile
Schleife wie dieser verwendet wird. Die spezielle Variable$.
enthält die Anzahl der bisher gelesenen Zeilen und%
ist der Moduloperator.Mit den Schaltern
-n
und kann dieser Code als Einzeiler noch kompakter geschrieben-e
werden:Der
-e
Schalter benötigt einen Teil des Perl-Codes, um als Befehlszeilenparameter ausgeführt zu werden, während der-n
Schalter den Code implizit in einewhile
Schleife wie die oben gezeigte einschließt.Bearbeiten: Um tatsächlich die Zeilen 1, 3, 6, 9, ... wie im Beispiel zu erhalten, anstelle der Zeilen 1, 4, 7, 10, ..., wie ich zuerst angenommen habe, dass Sie es wollten, ersetzen Sie sie
$. % 3 == 1
durch$. == 1 or $. % 3 == 0
.quelle
Wenn Sie es mit einem Bash- Skript machen möchten, können Sie versuchen:
Speichern Sie es als "read_lines.sh" und denken Sie daran, der Bash-Datei + x-Berechtigungen zu erteilen.
quelle
./read_lines.sh > new_file.txt
.Eine Lösung in Pure Bash, die keinen Prozess hervorbringt, ist:
Die erste Zeile überspringt 2 Zeilen am Anfang der Datei, und
while
die nächste Zeile wird gedruckt, und es werden 2 Zeilen erneut übersprungen.Wenn Ihre Datei klein ist, ist dies eine sehr effiziente Methode, um den Job auszuführen, da kein Prozess gestartet wird. Wenn Ihre Datei groß ist,
sed
sollten Sie sie verwenden, da sie effizienter mit io umgeht alsbash
.quelle
Eine Python-Version (sowohl Python 2 als auch Python 3):
Ersetzen Sie sie
[::3]
durch Start-, End- und Schrittgrößenparameter, um mehr Kontrolle zu haben. ZB[10:36:5]
Zeilen 10, 15, ..., 35.Da
readlines()
die Zeilenenden beibehalten werden, endet die Ausgabe dieses Aufrufs möglicherweise mit einer leeren letzten Zeile, es sei denn, die ursprüngliche letzte Zeile wird mit der ausgewählten Schrittgröße ausgegeben.Auch eine Stream-Version ist möglich (hier erst nach beendetem Stream ausgeben):
quelle