Schrift
[thread]8934[/thread]

In "grep" ZWEI Bedingungen erfüllen

Leser: 2


<< |< 1 2 3 >| >> 24 Einträge, 3 Seiten
Gast Gast
 2007-04-20 16:56
#76084 #76084
Würde mich über einen Lösungsvorschlag freuen.
Leider bin ich trotz Recherche im Netz noch nicht fündig geworden.
Ich möchte bestimmte (doppelte) Datensätze aus einem Feld (@found) mit "grep" löschen.
Genauer gesagt darf ein Datensatz nur 1 mal erhalten bleiben, wenn 2 Bedingungen
erfüllt sind.
Irgendwie bin ich zu blöd für einen korrekten Syntax der Formel mit dem Befehl "grep" 2 Bedingungen
einzubauen -(

Die Struktur der generierten Datensätze ist:
push(@found,$Treffer."\t".$GanzeURL."\t".$IrgendeinText."\t".$DomainName)


Ich formuliere die Aufgabe mal auf "Hochdeutsch".

Wenn $DomainName in $GanzeURL enthalten ist && $Treffer <= $Treffer( der vorherigen Treffer) ist

DANN

Lösche alle doppelten Datensätze dieser zwei Bedingungen und erhalte EINEN oder alternativ auch ZWEI dieser Datensätze.

Für eine Hilfe wäre ich sehr Dankbar.
renee
 2007-04-20 17:03
#76085 #76085
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Code (perl): (dl )
1
2
my $tmp_treffer;
my @unique = grep{ index($GanzeUrl,$DomainName) != 0 and $Treffer <= $tmp_treffer and $tmp_treffer = $Treffer }@ausgangsarray


(ungetestet)
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Meo
 2007-04-20 18:12
#76086 #76086
User since
2007-04-20
12 Artikel
BenutzerIn
[default_avatar]
Erst mal Danke für die schnelle Hilfe! Aber es klappt noch nicht. Deshalb meine Nachfragen:

Ich habe Deine Lösung erst ein mal so umgesetzt:

Code: (dl )
1
2
my $tmp_treffer;
my @unique = grep{ index($ausgangsarray[1],$ausgangsarray[3]) != 0 and $ausgangsarray[0] <= $tmp_treffer and $tmp_treffer = $ausgangsarray[0] }@ausgangsarray


Kann bestimmt auch nicht gehen, da keine Werte für z. B. $tmp_treffer von Aussen dazu kommen, sondern nur innerhalb des @ausgangsarry geprüft werden kann und soll. Das Gleiche natürlich für die Variablen $Domain und $GanzeURL.
Alle Werte befinden sich ja schon in dem @ausgangsarry.

@unique enthält demnach bei mir keine Inhalte mehr.

Vielleicht bin ich noch zu unerfahren, Deine Formel korrekt umzuwandeln bzw. anzupassen?

edit pq: code-tags hinzugefügt\n\n

<!--EDIT|pq|1177160917-->
Meo
 2007-04-20 20:01
#76087 #76087
User since
2007-04-20
12 Artikel
BenutzerIn
[default_avatar]
Oder mal ganz anders. Lassen wir die $Treffer - Auswertung ganz bei Seite.
Mein Hauptfeld (@found) beinhaltet ja bereits eine Reihe von Datensätze, die über
Code: (dl )
push(@found,$Treffer."\t".$GanzeURL."\t".$IrgendeinText."\t".$DomainName)

generiert wurden.
Davon möchte ich Doppelte Datensätze entfernen, die aber nur an EINER Stelle auf Doppelung geprüft und ausgewertet werden.
In meinem Fall ist es nur der dritte Eintrag ($DomainName) pro Datensatz, also der Eintrag am Schluss, der via "grep" berücksichtigt werden soll.

Code: (dl )
1
2
%seen;
@unique = grep {! $seen{$_}++} @found;

z. B. vergleicht alle Einträge pro Datensatz. Ich möchte aber nur das der Eintrag am Schluss auf Doppelungen geprüft werden und letztendlich EIN Datensatz davon erhalten bleibt.

Sorry, wenn ich mich nicht ganz so professionell ausdrücke und das jetzige Beispiel ein anders ist.

edit pq: code-tags hinzugefügt\n\n

<!--EDIT|pq|1177160973-->
renee
 2007-04-20 20:07
#76088 #76088
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wie sieht denn der Inhalt von des Ausgangsarrays aus und was soll am Ende übrigbleiben. Bitte nicht nur beschreiben, sondern auch mal ein kleines Beispiel posten...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Meo
 2007-04-20 20:37
#76089 #76089
User since
2007-04-20
12 Artikel
BenutzerIn
[default_avatar]
Die  Inhalte des Ausgangsarrays habe ich in einer Schleife mit "push" generiert
Beispiel:
Code: (dl )
push(@found,$Treffer."\t".$GanzeURL."\t".$IrgendeinText."\t".$DomainName)


Die einzelnen Daten habe ich darin mit TAB (."\t".) getrennt. Am Ende steht automatisch immer ein "\r".

Bei der Print-Ausgabe durch
Code: (dl )
1
2
3
4
for(@found) {
@output = split(/\t/,$_);
print "<p>Trefferanzahl: $output[0] - URL: $output[1] - Infotext: $output[2] - HauptDomain: $output[3]";
}

kommt zum Beispiel mit folgendes heraus:

Code: (dl )
1
2
3
4
Trefferanzahl: 14 - URL: [URL=http://www.domain-a.de/unterseite/]http://www.domain-a.de/unterseite/[/URL] - Infotext: Bla bla... - HauptDomain: www.domain-a.de
Trefferanzahl: 19 - URL: [URL=http://www.domain-b.de/unterseite/]http://www.domain-b.de/unterseite/[/URL] - Infotext: Bla bla... - HauptDomain: www.domain-b.de
Trefferanzahl: 16 - URL: [URL=http://www.domain-c.de/unterseite/]http://www.domain-c.de/unterseite/[/URL] - Infotext: Bla bla... - HauptDomain: www.domain-c.de
Trefferanzahl: 20 - URL: [URL=http://www.domain-c.de/unterseite/]http://www.domain-c.de/unterseite/[/URL] - Infotext: Bla bla... - HauptDomain: www.domain-c.de

usw.

Ich möchte das Array nun mit "grep" auf Doppelungen durchsuchen, wo nur die Datensätze entfernt werden, von denen bereits eine HauptDomain enthalten ist.
Eine HauptDomain muss immer erhalten bleiben. Welche wäre erst mal egal.

Ganz edel wäre natürlich die, mit der höchsten Trefferanzahl. Aber das könnte ich durch vorherige Sortierung auch selbst vorbereiten.

Im neuen Ziel-Array soll dann alles so geschrieben werden, wie das Array @found vorher aufgebaut war. Also alle restlichen Daten (wie Treffer usw.) und die Trennung mit TAB wäre wichtig erhalten zu lassen.

edit pq: code-tags hinzugefügt\n\n

<!--EDIT|pq|1177161031-->
PerlProfi
 2007-04-20 21:16
#76090 #76090
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Warscheinlich viel zu umständlich sollte folgendes dein gewünschtes Ergebnis erzielen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# get doubles
my %seen;
foreach my$key (@found) {
my @ele = split("\t", $key);
$seen{$ele[-1]} = [] unless $seen{$ele[-1]};
push(@{$seen{$ele[-1]}}, [$i, $ele[0]]);
}

# delete doubles
my $i = 0;
foreach my$key (keys %seen) {
if (@{$seen{$key}} > 1) {
# sort
my $top = $seen{$key}->[0];
foreach my$act (@{$seen{$key}})
{ if ($act->[1] > $top->[1]) { $top = $act } }

# splice
foreach my$act (@{$seen{$key}})
{ if ($act->[0] != $top->[0]) { splice(@found, $act->[0]-$i, 1); ++$i } }
}
}


MfG
Meo
 2007-04-20 21:31
#76091 #76091
User since
2007-04-20
12 Artikel
BenutzerIn
[default_avatar]
Erst mal Danke!
Welches soll das Array mit der Auswertung sein?
Leider verstehe ich den code nicht, liegt aber noch an meinen fehlenden Kenntnissen.
Der erste Versuch brachte noch nicht das gewünschte Ergebnis. Ich probiere mal noch etwas rum...
PerlProfi
 2007-04-20 21:43
#76092 #76092
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Das Array mit der Auswertung wäre hier @found.

Wenn du also dieses code stück in einen Block tuen würdest, und dann in dem Block, vor dem code dein Array mit der Auswertung an @found zuweisen würdest, sollte es klappen, ich habs nicht getestet, aber ich denke es sollte klappen:
Code: (dl )
1
2
3
4
{
my @found = @dein_array_mit_der_auswertung;
# der restliche o.g. code
}
Meo
 2007-04-20 21:47
#76093 #76093
User since
2007-04-20
12 Artikel
BenutzerIn
[default_avatar]
okay, ich probiere das gleich mal aus. auf jeden fall ist dein code schon mal nahe dran :-)

Rückmeldung folgt...
<< |< 1 2 3 >| >> 24 Einträge, 3 Seiten



View all threads created 2007-04-20 16:56.