2009-07-01 4 views
0

Ich habe eine Textdatei mit 2 Millionen Zeilen. Jede Zeile enthält Transaktionsinformationen.Kopieren eines Teils einer großen Datei mit der Befehlszeile

z.B.

23848923748, Beispieltext, feild2, 12/12/2008

etc

Was ich will weiter eine neue Datei aus einer bestimmten eindeutigen Transaktionsnummer erstellen tun. Also möchte ich die Datei an der Zeile teilen, wo diese Nummer existiert.

Wie kann ich das Formular der Befehlszeile machen?

Ich kann die Linie finden, indem dies zu tun:

cat myfile.txt | grep 23423423423 

Antwort

2

Auf einer zufällige Datei in meinem tmp Verzeichnis, das ist, wie ich alles ausgeben, von der Linie popd an in einer Datei namens tmp.sh passend:

tail -n+`grep -n popd tmp.sh | cut -f 1 -d:` tmp.sh 

tail -n+X Spiele von dieser Zeilennummer ab; grep -n gibt Linneno: Dateiname aus und schneidet nur Ausschnitte lineno von grep aus.

für Ihren Fall So wäre es:

tail -n+`grep -n 23423423423 myfile.txt | cut -f 1 -d:` myfile.txt 

Und es sollte in der Tat ab dem ersten Auftreten entspricht.

+0

Prost, das hat einen Charme funktioniert. –

+0

gut um genauer zu sein, dies funktioniert tail -n + 'grep -n 23423423423 myfile.txt | Schnitt -f 1 -d: 'myfile.txt> newfile.txt –

+0

@Derek, ich war überrascht zu sehen, dass Sie einen Schwanz + Grep + Schnitt über einen einfachen Stream bearbeiten bevorzugt ... – nik

0

Es ist keine schöne Lösung, aber wie wäre es -A Parameter von grep?

So:

[email protected]:/tmp$ cat a 
1 
2 
3 
4 
5 
6 
7 
[email protected]:/tmp$ cat a | grep 3 -A1000000 
3 
4 
5 
6 
7 

Das einzige Problem, das ich in dieser Lösung sehen, ist die 1000000 magische Zahl. Wahrscheinlich wird jemand die Antwort wissen, ohne einen solchen Trick zu benutzen.

0

Sie können die Zeilennummer wahrscheinlich mit Grep abrufen und dann mit Tail die Datei von diesem Punkt aus in die Ausgabedatei drucken.

Entschuldigung, ich habe keinen tatsächlichen Code zu zeigen, aber hoffentlich ist die Idee klar.

3

Verwendung sed wie dies

sed '/23423423423/,$!d' myfile.txt 

bestätigt nur, dass die eindeutige Transaktionsnummer nicht als ein Muster in einem anderen Teil der Linie (vor allem vor der richtig passenden Zeile) in der Datei angezeigt werden kann.


Es gibt bereits ein 'perl' hier beantworten, so, werde ich einen weiteren AWK Weg geben :-)

awk '{BEGIN{skip=1} /number/ {skip=0} // {if (skip!=1) print $0}' myfile.txt 
+0

es sollte nicht zweimal erscheinen, aber nur für den Fall, dass es tat, wie könnte ich es ändern, so dass es vom ersten Vorkommen bis zum Ende der Datei funktioniert. –

+0

Erhalten Sie ein konstantes Muster, das die Übereinstimmung nur mit der Transaktionsnummer qualifiziert. Wie ist die Nummer als erstes auf der Linie? (dann pass auf "^ Nummer"), Ist ein Leerzeichen vorangestellt oder ein Suffix oder das ':' Zeichen? (Versuchen Sie "Nummer:", usw.). – nik

+0

'awk '/ 23423423423 /, 0 {print}' 'ist kürzer - in der Tat können Sie sogar' {print}' auswerfen, da dies die Standardaktion ist. – ephemient

0

Ich würde ein schnellen Perl-Skript schreiben, ehrlich gesagt. Es ist von unschätzbarem Wert für so etwas (relativ einfache Probleme) und sobald etwas komplexer wird (wie es wird!), Dann brauchen Sie die zusätzliche Kraft.

Etwas wie:

#!/bin/perl 

my $out = 0; 
while (<STDIN>) { 
    if /23423423423/ then $out = 1; 
    print $_ if $out; 
} 

und führen Sie es mit:

$ perl mysplit.pl <input> output 

Nicht getestet, ich habe Angst.

+0

Kürzere: perl -ne 'Drucken if/23423423423/.. eof()' – ephemient

+0

Das ist besser. Ich war mir bewusst, dass Sie das tun konnten, aber die Details usw. vergessen hatten. –

+0

Ich habe dies leicht modifiziert, um es zum Laufen zu bringen (und um Groß- und Kleinschreibung zu ignorieren, wenn ich nach einer Textzeichenfolge suche). Ich änderte die if-Anweisung zu: if ($ _ = ~/stevens/i) {$ out = 1;} Hoffen, dass das für jemanden von Interesse ist. – DBMarcos99

Verwandte Themen