2017-02-26 3 views
-2

Ich habe eine Online-Perl-Konkordanz, die nach einem Zielwort in einer bestimmten Textdatei sucht und die sortierte Ausgabe druckt. Der Testcode sucht derzeit nur in einer einzelnen Textdatei nach dem Schlüsselwort und gibt die Ausgabe aus. Aber ich möchte das gleiche für alle Textdateien im Ordner und nicht nur für eine einzelne Textdatei tun. Jeder Vorschlag diesbezüglich wäre sehr hilfreich. HierEingabe mehrerer TXT-Dateien in Perl

ist der Code für meine Online-Konkordanz:

#!/usr/bin/perl -wT 

# require 
use strict; 
use diagnostics; 
use CGI; 

# sanity check 
my $q = new CGI; 
my $target = $q->param("keyword"); 
my $radius = $q->param("span"); 
my $ordinal = $q->param("ord"); 
my $width = 2*$radius; 
my $file = 'DISS.G.HB.002.txt'; 
if (! $file or ! $target) { 

    print "Usage: $0 <file> <target>\n"; 
    exit; 

} 

# initialize 
my $count = 0; 
my @lines =(); 
$/   = ""; # Paragraph read mode 

# open the file, and process each line in it 
open(FILE, " < $file") or die("Can not open $file ($!).\n"); 
while(<FILE>){ 

    # re-initialize 
    my $extract = ''; 

    # normalize the data 
    chomp; 
    s/\n/ /g;  # Replace new lines with spaces 
    s/\b--\b/ -- /g; # Add spaces around dashes 

    # process each item if the target is found 
    while ($_ =~ /\b$target\w*/gi){ 

     # find start position 
     my $match = $1; 
     my $pos = pos; 
     my $start = $pos - $radius - length($match); 

     # extract the snippets 
     if ($start < 0){ 
      $extract = substr($_, 0, $width+$start+length($match)); 
      $extract = (" " x -$start) . $extract; 
     }else{ 
      $extract = substr($_, $start, $width+length($match)); 
      my $deficit = $width+length($match) - length($extract); 
      if ($deficit > 0) { 
       $extract .= (" " x $deficit); 
      } 

     } 

     # add the extracted text to the list of lines, and increment 
     $lines[$count] = $extract; 
     ++$count; 

    } 

} 

sub removePunctuation { 
    my $string = $_[0]; 
    $string = lc($string); # Convert to lowercase 
    $string =~ s/[^-a-z ]//g; # Remove non-aplhabetic characters 
    $string =~ s/--+/ /g; #Remove 2+ hyphens with a space 
    $string =~s/-//g; # Remove hyphens 
    $string =~ s/\s=/ /g; 
    return($string); 

} 

sub onLeft { 
    #USAGE: $word = onLeft($string, $radius, $ordinal); 
    my $left = substr($_[0], 0, $_[1]); 
    $left = removePunctuation($left); 
    my @word = split(/\s+/, $left); 
    return($word[-$_[2]]); 
} 

sub byLeftWords { 
    my $left_a = onLeft($a, $radius, $ordinal); 
    my $left_b = onLeft($b, $radius, $ordinal); 
    lc($left_a) cmp lc($left_b); 
} 


# process each line in the list of lines 

print "Content-type: text/plain\n\n"; 
my $line_number = 0; 

foreach my $x (sort byLeftWords @lines){ 
    ++$line_number; 
    printf "%5d",$line_number; 
    print " $x\n\n"; 
} 

# done 
exit; 
+0

Siehe auch [Lingua :: Konkordanz] (https://metacpan.org/pod/Lingua::Concordance) –

+1

Also ... Sie haben mehr als 100 Zeilen Code geschrieben --- die Sie hier abgelegt haben in seiner Gesamtheit --- aber Sie könnten nicht einmal versuchen, etwas wie ['glob'] (http://perldoc.perl.org/functions/glob.html) oder [' readdir'] (http: //perldoc.perl.org/functions/readdir.html) um ein Verzeichnis zu scannen? –

+0

@Matt, Ihre Antwort ist auch nicht hilfreich. Deep Shah hat vor anderthalb Monaten Probleme gehabt und versucht, sein CGI zum Laufen zu bringen, und bleibt wieder stecken. Hier kommt sein massiver Code-Dump her. Hoffentlich kann Ihr 'readdir'-Vorschlag etwas Fortschritt machen ... aber @Matt kann es besser machen - grtzzz – vanHoesel

Antwort

1

Die glob() Funktion wird eine Liste der Dateien zurück, die mit einem Muster übereinstimmen.

my @text_files = glob('*.txt'); 

Natürlich müssen Sie wahrscheinlich nicht die Zwischen @text_files variabel.

while (my $file = glob('*.txt')) { 
    open my $fh, '<', $file or die "$file: $!"; 
    # do something with the filehandle 
} 

Einige andere Vorschläge für Ihren Code.

  • -w wurde weitgehend mit use warnings ersetzt, wenn Perl 5.6 im Jahr 2000
  • new CGI veröffentlicht wurde besser ist weit CGI->new geschrieben.
  • Änderungen an speziellen Variablen (wie $/) sollten immer lokalisiert werden.
  • Bitte verwenden Sie lexikalische Dateihandles und die Drei-Arg-Version von open() (wie in meinem Beispiel oben gezeigt).
  • Wenn Sie CGI.pm verwenden, warum nicht auch seine header() Methode verwenden?

Aber, am wichtigsten, bitte überdenken Sie Ihre Verwendung von CGI. Bitte lesen Sie CGI::Alternatives für etwas bessere (womit ich meine, einfacher und mächtiger) Vorschläge.

+0

Vielen Dank für Ihre Hilfe –

Verwandte Themen