2009-07-01 5 views
0

J'ai un fichier texte avec 2 millions de lignes. Chaque ligne contient des informations sur les transactions.Copie d'une partie d'un fichier volumineux à l'aide de la ligne de commande

par exemple.

23848923748, exemple de texte, feild2, 12/12/2008

etc

Ce que je veux faire est de créer un nouveau fichier à partir d'un certain nombre de transaction unique à compter. Donc, je veux diviser le fichier à la ligne où ce numéro existe. Comment puis-je faire cela en ligne de commande?

je peux trouver la ligne en faisant ceci:

cat myfile.txt | grep 23423423423 

Répondre

2

Sur un fichier aléatoire dans mon répertoire tmp, voilà comment je tout sortie de la ligne correspondant à partir popd dans un fichier nommé tmp.sh:

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

tail -n+X matchs de ce numéro de ligne partir; grep -n sort lineno: nom de fichier, et extrait extraits juste lineno de grep.

Donc, pour votre cas, il serait:

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

Et il devrait en effet correspondre à partir de la première occurrence partir.

+0

acclamations, qui a travaillé un charme. –

+0

bien pour être plus précis cela a fonctionné queue -n + 'grep -n 23423423423 myfile.txt | cut -f 1 -d: 'myfile.txt> newfile.txt –

+0

@Derek, j'ai été surpris de vous voir préférer une queue + grep + couper un simple flux éditer ... – nik

0

Ce n'est pas une solution assez, mais que diriez-vous en utilisant le paramètre -A de grep?

Comme ceci:

[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 

Le seul problème que je vois dans cette solution est le nombre magique 1000000. Probablement quelqu'un connaîtra la réponse sans utiliser un tel tour.

0

Vous pouvez probablement obtenir le numéro de ligne en utilisant Grep, puis utiliser Tail pour imprimer le fichier à partir de ce point dans votre fichier de sortie.

Désolé je n'ai pas de code réel à afficher, mais j'espère que l'idée est claire.

3

utilisation sed comme celui-ci

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

ne font que confirmer que le numéro de transaction unique ne peut pas apparaître comme un modèle dans une autre partie de la ligne (en particulier, avant la ligne correspondant correctement) dans votre fichier.


Il existe déjà un 'perl' répondre ici, donc, je vais donner un plus AWK façon :-)

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

il ne devrait pas apparaître deux fois mais juste au cas où il l'a fait, comment pourrais-je le modifier afin qu'il fonctionne de la première occurrence à la fin du fichier. –

+0

Obtenez un motif constant qui qualifiera la correspondance à se produire uniquement avec le numéro de transaction. Comme est le numéro première chose sur la ligne? (puis, correspondre "^ numéro"), Est-il préfixé ou suffixe avec un espace ou dire le caractère ':'? (essayez "numéro:", etc). – nik

+0

'awk '/ 23423423423 /, 0 {print}' 'est plus court - en fait, vous pouvez même jeter' {print} ', car c'est l'action par défaut. – ephemient

0

Je voudrais écrire un script Perl rapide, franchement. Il est inestimable pour n'importe quoi de pareil (problèmes relativement simples) et dès que quelque chose de plus complexe fait sa tête (comme il le fera!) Alors vous aurez besoin de la puissance supplémentaire.

Quelque chose comme:

#!/bin/perl 

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

et l'exécuter en utilisant:

$ perl mysplit.pl <input> output 

Non testé, j'ai peur.

+0

Shorter: perl -ne 'imprimer si/23423423423/.. eof()' – ephemient

+0

C'est mieux. Je savais que vous pouviez le faire mais j'avais oublié les détails, etc. –

+0

Je l'ai légèrement modifié pour le faire fonctionner (et aussi pour ignorer le cas si je cherchais une chaîne de caractères). J'ai changé l'instruction if à: if ($ _ = ~/stevens/i) {$ out = 1;} J'espère que cela intéresse quelqu'un .. – DBMarcos99

Questions connexes