Здравствуйте, Господа. Помогите пожалуйста пофиксить программу ,
которая сравнивает два текстовых файла и в результате выводит в новый
.txt предложения которых нет ни в одном из двух файлов. Скрипт выглядит следующим образом:#!/usr/bin/perl
use open ':utf8';
binmode (STDOUT, ":utf8");
open (DATA, "10_saetze_aus_neg.txt") or die "alle_saetze_aus_neg1_sort.txt gibt es nicht\n";
open (IN, "500_appendix.txt");
while (<IN>){
chomp;
$str[$i++]=lc($_);
$str[$i-1]=~ s/[\,\.\?\-\!\"\*\;\:]//g;
$str[$i-1]=~ s/ / /g;
$str[$i-1]=~ s/ / /g;
$str[$i-1]=~ s/^ //g;
$str[$i-1]=~ s/\015\000$//g;
$str[$i-1]=~ s/ $//g;}
close (IN);
while(<DATA>){
chomp;
$dat[$m++]=lc ($_);
$dat[$m-1]=~ s/ / /g;
$dat[$m-1]=~ s/ / /g;
$dat[$m-1]=~ s/^\s*(\S.*)/$1/;
# $dat[$m-1]=~ s/^(\S.*)\s*$/$1/;
$dat[$m-1]=~ s/^ //;
$dat[$m-1]=~ s/^ //;
$dat[$m-1]=~ s/^ //;
$dat[$m-1]=~ s/\015\000$//g;
$dat[$m-1]=~ s/ $//g;
$dat[$m-1]=~ s/ $//g;
$dat[$m-1]=~ s/ $//g;
}
close (DATA);open (OUT, ">>neue_saetze.txt");
for ($k = 0; $k < $i; $k++){
$exist = 1;
print "m: $m\ti: $i\n";for ($j = 0; $j < $m; $j++){
if ($str[$k] eq $dat[$j]){
$exist = 0;
}
}
if ($exist == 1){
print OUT $str[$k]."\n";
}
}
close (OUT);
Заранее благодарю.
ффтопкуты словами напиши, что ты хочешь сделать. А то в одном файле ты удаляешь знаки препинания, в другом - нет. С пробелами много раз делаешь что-то одинаково неприличное. Что ты называешь предложением?
#!/bin/sh
cat $* | sed 's/\s\{2,\}/ /g' | tr [:upper:] [:lower:] | sort | uniq -c
недостаточно?
>ты словами напиши, что ты хочешь сделать.Да, наверное, действительно лучше рассказать словами. Значит по порядку:
- есть текстовый файл 1.txt. В нем содержатся предложения (каждое с новой строки) со знаками препинания, отсортированныe в алфавитном порядке (предположим таких предложений 500)
- есть текстовый файл 2.txt, в котором содержатся идентичные предложения (таких предложений 100) из файла 1.txt, только без каких- либо знаков препинания, все буквы в нижнем регистре.
- задача состоит в том чтобы убрать из 1.txt те предложения, которые есть в fail 2.txtБлагодарю Вас за идеи.
>предложений 100) из файла 1.txt, только без каких- либо знаков
>препинания, все буквы в нижнем регистре.
>- задача состоит в том чтобы убрать из 1.txt те предложения, которые
>есть в fail 2.txtmy %src = ();
open FILE1,...
open FILE2,...while (<FILE2>) {
chomp;
s/\s{2,}/ /go;
$src{$_} = 1;
}my $dst;
while (<FILE1>) {
$dst = $_;
chomp;
lc;
s/[:punct:]//go;
s/\s{2,}/ /go;
print $dst unless ($src{$_});
}
Спасибо огромное за Ваши идеи и помощь!!! Ваша поддержка придает мне сил, оптимизма и желания учить перл дальше!
>...предложения которых нет ни в одном из двух файлов.Вот этого я, честно говоря, недопонял.
Откуда же возьмется предложение, если его нет ни в одном из двух файлов :)Если ты хочешь вывести файл строк, которые не повторяются - загоняй строки обоих файлов в хэш в качестве ключей, перебирай 2 хэша и увеличивай занечение, соответсвующее ключу, если такая строка встретилась. Потом в файл выплюнешь все ключи, значения которых равны 0.
Надеюсь доступно. Это упрощенный способ.
>Если ты хочешь вывести файл строк, которые не повторяются - загоняй строки
>обоих файлов в хэш в качестве ключейСпасибо за конструктивное предложение. Отличный ход мысли. Но попытавшись воплотить Ваш замысел в жизнь, на почве не глубоких познаний, возник вопрос: Что бы завести сразу все строки в хеш нужно написать примерно так ?:
$var = "/home/local/file1.txt"
open (FILE, "$var");
my @array=();
?
>>Если ты хочешь вывести файл строк, которые не повторяются - загоняй строки
>>обоих файлов в хэш в качестве ключей
>
>Спасибо за конструктивное предложение. Отличный ход мысли. Но попытавшись воплотить Ваш замысел
>в жизнь, на почве не глубоких познаний, возник вопрос: Что бы
>завести сразу все строки в хеш нужно написать примерно так ?:
>
> $var = "/home/local/file1.txt"
> open (FILE, "$var");
> my @array=();
>?Нет. Это Массив.
Тебе нужен хэш.
# загоняешь первый файл в хэш;
open (F,'file1')||die "Cannot read file: $!";
while(<F>)
{
chomp;
$hash1{$_}=0;
}
close(F);
# Открываешь второй файл....
open(F,'file2')||die "Cannot read file: $!";
while(<F>)
{
chomp;
# Проверяешь, если в первом файле такая строка уже была
if ($hash1{$_})
{
# Удаляешь ее и не запоминаешь...
delete($hash1{$_});
}
else
{
# Иначе добавляешь в хэш
$hash2{$_}=0;
}
}
close(F);# Выкидываешь в файл-результат все строки, котрых не было ни в одном их двух файлов.
open(W,'>result')||die "Cannot write file: $!";
foreach(keys(%hash1))
{
print W '$_\n';
}
foreach(keys(%hash2))
{
print W "$_\n";
}
close(W);
Самые искренние благодарности!!!
Я с этой программулиной уже целую вечность мучаюсь :) Единственое, что не дает мне покоя, это следующий кусок:
open(OUT,">rez.txt");
my @not=();
foreach(keys %hash1){
push(@not,$_) unless exists $hash2{$_};
print OUT ("$_ /n");
close (OUT);
Ума не приложу почему он не рабочий!
А еще есть странный баг: в результирующем файле помимо всех несовпадающих строк попалась одна повторяющаяся, при чем два раза (но не подряд) : /И еще, подскажите пожалуйста, будет ли достаточно строки use locale для работы с кирилицей?