J'espère que le sujet est assez clair, je n'ai rien trouvé spécifiquement à ce sujet dans le bac précédemment demandé. J'ai essayé de la mettre en œuvre dans Perl ou Python, mais je pense que je suis peut-être trop difficile.
Y a-t-il une simple commande / pipeline shell qui scindera mon fichier 4MB .txt en fichiers SEPérer .txt, basé sur un début et finissant regex? p>
i Fournissez un bref échantillon du fichier ci-dessous .. Vous pouvez donc voir que chaque "histoire" commence par la phrase "x xxx documents", qui pourrait être utilisée pour diviser le fichier . P>
Je pense que cela devrait être facile et je serais surpris si Bash ne peut pas le faire - plus rapide que Perl / py. P>
Ici, il est: p> < Pré> xxx pré>
Merci d'avance pour toute votre aide. P>
Ross P> P>
5 Réponses :
regex pour correspondre à "x des documents xxx" est
\ D {1,3} de \ D {1,3) Documents P>
ligne de lecture par ligne et commençant à écrire un nouveau fichier sur REGEX Match doit être bien. P>
non testé:
Au fait, ce qui précède est pure bash. En outre, je suis sûr que Python ou Perl serait beaucoup plus rapide.
Pouvez-vous le faire avec CSplit? CSplit -K -Z -Z -Digits = 3 --Suffix = '% d.txt' --Prefix = fichier * .txt / 'splitontris'
@ROSSER - Il s'agit d'un candidat pour Split, ne connaissez pas la csplit
@SLN: Split code> est des fichiers de sortie de taille fixe plutôt que des regextes. @ROSSER:
CSplit code> est une possibilité définitive.
Dans quelle mesure avez-vous essayé dans Perl?
edit fort> Voici une méthode plus rapide. Il divise le fichier puis imprime les fichiers de pièces. P> use strict;
use warnings;
open (my $masterfile, '<', 'yourfilename.txt') or die "Can't open yourfilename.txt: $!";
my $count = 1;
my $fh;
while (<$masterfile>) {
if ( /(?<!\d)(\d+)\s*of\s*\d+\s*DOCUMENTS/ ) {
defined $fh and close ($fh);
open ($fh, '>', "Part$1_$count.txt") or die "Can't open Part$1_$count for output: $!";
$count++;
next;
}
defined $fh and print $fh $_;
}
defined $fh and close ($fh);
close ($masterfile);
$ Nombre code> est indéfini. Je soupçonne que vous vouliez dire
$ CNT code>. En outre, la première fois que vous exécutez via la boucle
$ fh code> est indéfinie, vous obtiendrez donc un
ne peut pas utiliser une valeur non définie comme référence de symbole CODE> ERROR / AVERTISSEMENT Vous essayez de fermer
$ fh code>.
Chemin sur ma tête à Perl - pas que je n'essaye pas ... Perl, Python, R, Bits de Ruby, Bash, un peu C ++. En plus d'être un médecin d'emploi et d'essayer de faire des recherches ... TA pour l'aide.
Pourrait aussi bien mettre un chèque sur la fin de la fin finale () aussi
@ROSSER - Oh, ce n'est pas si mal à Perl. Une version rasée peut être effectuée à partir de la ligne de commande, une soi-disant 1 revêtement.
Impossible d'utiliser une valeur non définie comme référence de symbole sur getfile.pl Line 16, <$ Masterfile> Ligne 1.
@Rosser - bonne prise! Votre droite, savez-vous comment le réparer? Défini $ FH et Imprimer $ FH $ _; CODE> C'était juste un exemple non testé, c'est fixé maintenant. Je l'écrirais probablement différemment pour mon usage.
#!/usr/bin/env ruby g=1 f=File.open(g.to_s + ".txt","w") open("file").each do |line| if line[/\d+ of \d+ DOCUMENTS/] f.close g+=1 f=File.open(g.to_s + ".txt","w") end f.print line end
Oh et nous avons un gagnant ... Vitesse et I> Elegance J'ai passé un été vraiment humide en 1997 avec le livre O'Reilly Sed / Awk. J'aimerais pouvoir me rappeler tout cela maintenant. Je va i> aller et l'obtenir TMRW. merci b>
Cette solution met la ligne de correspondance dans le nouveau fichier, qui répond à la question. Mais si, comme moi, vous voulez mettre la ligne correspondante dans l'ancien fichier avant de commencer le nouveau, vous feriez ceci: awk '{imprimer $ 0> n ".txt"} / texte à correspondre / { n ++} code>
Remarque: sur Mac OS X, vous avez besoin GAWK code> de par exemple. Macports pour cela pour travailler
Comme suggéré dans d'autres solutions, vous pouvez utiliser csplit code> pour celui-ci:
csplit csplit.test '/^\.\.\./' '{*}' && sed -i '/^\.\.\./d' xx*
Je ne peux pas essayer maintenant car sur Windows, mais la page de l'homme de Csplit semble suggérer d'utiliser% REGEX% au lieu de / regex / pour cela: / Regexp / [décalage] Copie jusqu'à mais non inclure une ligne de correspondance% REGEXP% [Décalage ] Passer à, mais pas inclure une ligne de correspondance
Est-ce un exemple de texte nécessaire?
Veuillez éditer et supprimer environ 95% du texte de votre question.
Dupliqué possible de Split un fichier en plusieurs fichiers en fonction de Délimiter a>