2015-06-30 2 views
1

Я любитель Perl. Недавно мне был предоставлен скрипт Perl, который принимает текстовый файл и удаляет все форматирование, за исключением того, что отдельные слова следует пробелу. Проблема в том, что скрипт неясно, как ввести расположение файла. Я создал некоторый код для запуска всего каталога файлов, но еще не смог выполнить код. Я отправлю исходный код, а затем добавлю. Спасибо за помощь!Нужна помощь в выполнении скрипта tolening perl

Оригинала:

while(<>) { 
    chomp; 
    s/\<[^<>]*\>//g;   # eliminate markup 
    tr/[A-Z]/[a-z]/;   # downcase 

    s/([a-z]+|[^a-z]+)/\1 /g; # separate letter strings from other types of sequences 

    s/[^a-z0-9\$\% ]//g;  # delete anything not a letter, digit, $, or % 

    s/[0-9]+/\#/g;    # map numerical strings to # 

    s/\s+/ /g;     # these three lines clean up white space (so it's always exactly one space between words, no newlines 
    s/^\s+//; 
    s/\s+$/ /; 


    print if(m/\S/);   # print what's left 
} 
print "\n"; # final newline, so whole doc is on one line that ends in newline 

Моих изменения:

#!/usr/local/bin/perl 

$dirtoget="1999_txt/"; 
opendir(IMD, $dirtoget) || die("Cannot open directory"); 
@thefiles= readdir(IMD); # 
closedir(IMD); 
    foreach $f (@thefiles) 
    { 
     unless (($f eq ".") || ($f eq "..")) 
     { 
      $fr="$dirtoget$f"; 
      open(FILEREAD, "< $fr"); 

$x=""; 
while($line = <FILEREAD>) { $x .= $line; } # read the whole file into one string 
close FILEREAD; 

print "$x/n"; 
while(<$x>) { 
    chomp; 
    s/\<[^<>]*\>//g;   # eliminate markup 
    tr/[A-Z]/[a-z]/;   # downcase 

    s/([a-z]+|[^a-z]+)/\1 /g; # separate letter strings from other types of sequences 

    s/[^a-z0-9\$\% ]//g;  # delete anything not a letter, digit, $, or % 

    s/[0-9]+/\#/g;    # map numerical strings to # 

    s/\s+/ /g;     # these three lines clean up white space (so it's always exactly one space between words, no newlines 
    s/^\s+//; 
    s/\s+$/ /; 


    print if(m/\S/);   # print what's left 
} 
print "\n"; # final newline, so whole doc is on one line that ends in newline 

}} 
+1

Похоже, ваш старый код был запущен как это: '$ Perl script.pl inputfile.txt> outputfile.txt', потому что он читает файл имя которого было предоставлено в качестве аргумента и 'print' результаты. Поэтому было бы целесообразно отправить этот вывод в новый файл. Если вы хотите, чтобы он просматривал больше файлов, напишите обертку в Perl или, возможно, в bash. – simbabque

+4

http://stackoverflow.com/questions/8023959/why-use-strict-and-warnings – TLP

+1

Вместо всех этих сложных замен, почему бы не просто захватить буквы (и цифры, если вы хотите '###')? Например. 'my @words = $ document = ~/[az] + | \ d +/gi' – TLP

ответ

1

Вам не нужно редактировать исходный скрипт, чтобы применить его к содержимому каталога. В этом случае оболочка будет вашим другом.

Ваш первый скрипт будет читать все файлы, переданные в качестве аргументов, или, по умолчанию, содержимое stdin. Других слов вы можете назвать свой оригинальный сценарий, как это:

$ ./script file > output 
$ cat file | ./script | less 

Если вы хотите, чтобы разобрать все файлы, которые вы все еще можете использовать оболочку:

$ ls | xargs -n1 -I{} sh -c "./script {} > {}.out" 

Это может быть яснее с этим коротким примером:

Рассмотрим подобный сценарий твоего имени script:

#!/usr/bin/perl 
while(<>) { 
    chomp 
    print ">$_<\n"; 
} 
print "\n"; 

Теперь от вас обстреливать вы можете сделать:

$ mkdir foo && cd foo 
$ echo -e "Hello\nYou\nI am A" >> a.txt 
$ echo -e "Hello\nYou\nI am A" >> b.txt 

$ ls | xargs -n1 -I{} sh -c "./script {} > {}.out" 

$ ls 
a.txt a.txt.out b.txt b.txt.out script script.out 
$ cat a.txt.out 
>Hello< 
>You< 
>I am A< 
+0

Я действительно не понимаю, что вы здесь делаете – Borodin

+0

@Borodin, я думал, что его вопрос состоял в том, как просто использовать его оригинал скрипт и применить его к каждому файлу в определенную папку. Я притворяюсь, что ему не нужно изменять скрипт, но просто используйте сценарий оболочки поверх своей оригинальной программы Perl. Я не прав? – nowox

1

Ваша главная проблема заключается в том, что вы открываете каждый файл и читать его содержимое в $x, а затем переходя $x как файловый дескриптор исходного контура. Но это не дескриптор файла - это просто текст. Если вы просто опустите чтение файла, то ваш код близок к работе

Я думаю, что это будет делать, как вы просите. Он использует glob в предпочтении к opendir/readdir, потому что это более кратким

#!/usr/local/bin/perl 

use strict; 
use warnings; 

while (my $file = glob '1999_txt/*') { 

    next unless -f $file; 

    open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!}; 

    while (<$fh>) { 
     chomp; 

     s/<[^<>]*>//g;    # Remove HTML tags 
     tr/A-Z/a-z/;    # downcase 

     s/([a-z]+|[^a-z]+)/$1 /g; # separate letter strings from other types of sequences 

     s/[^a-z0-9\$\% ]//g;  # delete anything not a letter, digit, $, or % 

     s/[0-9]+/#/g;    # map numerical strings to # 

     s/\s+/ /g;     # these three lines clean up whitespace 
     s/^\s+//;     # so it's always exactly one space 
     s/\s+$//;     # between words, no newlines 

     print if /\S/;    # print what's left if it's not just whitespace 
    } 

    print "\n"; # final newline, so whole doc is on one line that ends in newline 
} 
Смежные вопросы