Inhalte in einer Datei suchen und Dateiname ausgeben

U

ulrich_kehder

Grünschnabel
Hallo zusammen,
ich bin ein ziemlicher Perl Neuling und habe ein Problem das ich mit Perl lösen möchte.

Ein Programm schreibt in das Verzeichnis: \spool\obj sehr viele Dateien im ASCII Format.
Der Dateiname wird von diesem Programm aufgrund der Programminternen ID Nummer und dem Datum vergeben.
Die Endung erfolgt je nach dem was für ein Job Schritt gerade ausgeführt wurde.
Als Beispiel kann eine Datei folgendermassen heisen: om2246206.1.c532.1.tf2

Mein Problem ist nun das in diesen Dateien (etwa 10000 Stück) je nach dem wie oft das Programm läuft,
nach einem bestimmten Inhalt gesucht werden soll. Als Beispiel die Nummernfolge: 61034709
über alle Datein und im gesammten Verzeichnis.

Mit einem Shell Script und den Befehlen .find und grep geht es leider nicht.
(find . -tyype f | xargs grep -i 61034709)
Da die Files zu groß sind und unsere AIX Version zu alt ist so das ich eine Fehlermeldung bekomme.

Ich möchte daher ein Programm schreiben in Perl, das in dem Verzeichnis die Nummernfolge sucht
und die Filenamen in dem diese Nummerfolge vorkommt in eine Ausgabe Datei schreibt.

Leider habe ich mit Perl noch nichts Programmiert, habt ihr vielleicht eine Lösung für mich wie ich das
bewerkstelligen könnte.

Vielen Dank

Gruß
Uli
 
hm, eigentlich wäre das wirklich der ideale Punkt für grep und find - wie lautete denn die Fehlermeldung und welche konkreten Optionen hast Du verwendet?

(anstatt xargs z.b. mal -exec verwenden...)
 
xargs sollte eigentlich auch unter AIX die Option "-n N" unterstützen; mit
Code:
( find . -type f | xargs -n 25 grep -i 61034709)
könntest du also jeweils 25 Dateien an grep übergeben. Damit sollten die auszuführenden Kommandozeilen schon einmal nicht zu lange werden (wenn dein ursprüngliches Problem mit ARG_MAX oder so zu tun hat).

(NB: Theoretisch könnte man mit
Code:
find . -type f -exec grep -i 61034709 {} \;
auch ohne "xargs" auskommen, und trotzdem sicherstellen, dass die Kommandos kurz genug bleiben; im konkreten Fall ist es aber wahrscheinlich doch deutlich effizienter, "grep" jeweils für ein ganzes Paket von Dateien zu starten als einmal pro Datei ...)

Wenn du bei "grep" noch die Option "-l" ergänzt, bekommst du nur die Dateinamen, und die Liste kannst du dann ja einfach in eine Datei schicken.

Gruss, A.
 
Danke für die Tips.
Ich bekomme die Fehlermeldung grep: 0652-226 Maximum line length of 2048 exceeded.
Wenn ich diesen String absetze ( find . -type f | xargs -n 25 grep -i 61034709)
 
Dann bekomme ich die gleiche Fehlermeldung
 
poste bitte mal die _exakte_ Zeile, die Du verwendet hast.
 
find . -type f -exec grep -i 61034709 {} \;
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

Es geht mir dem grep befehl nicht im dem Unix Shell daher meine Frage ob ich das gleiche mit Perl lösen kann. Ich habe es schon ausführlich getestet.
 
Zuletzt bearbeitet:
klar kannst Du das auch mit Perl lösen. Die Frage ist nur - erwartest Du ernsthaft, daß Du in einem Forum "so mal nebenbei" einen kompletten Perl-Kurs bekommst oder daß die hier jemand das Script fertig schreibt?
 
Folgende Script hätte ich als Vorschlag aber momentan bringt es mir einen Syntax Fehler.
0403-057 Syntax error at line 2 : `('

#!/bin/pl
opendir (DIRH, "/usr/ediserv/spool/obj") || die "can not open: $!";
foreach my $file (sort readdir <DIRH>)
{
open(FH, "<$file") || die "can not open $file: $!";
my $line_count=0
foreach my $line (<FH>)
{
$line_count++;
if ($line =~ m/61034709/)
{
print "Pattern gefunden in Zeile $line_count in $file"
open(OUTFILE, ">$file") || die "$!"
print OUTFILE "ausgabe\n";
close(OUTFILE);
}
}
close(FH);
}
closedir(DIRH);

zu deiner Frage, ja ich erwarte das ernsthaft so wie es in anderen Foren auch passiert wenn man eine Lösungsmöglichkeit sucht.
 
Hi,

zum posten von Code hat das Board
Code:
 Bloecke, es waere gut wenn du die nutzen koenntest, das macht deine Posts lesbarer.

Kurzes googlen nach der Fehlermeldung spuckt u.a. folgendes aus:
http://www.issociate.de/board/post/291251/Grep_and_%22Maximum_line_length_of_2048_exceeded%22_errors.html

Hast du fold mal probiert? Das einzig dumme dabei ist natuerlich, dass das Muster das du suchst dann nicht gefunden wird, wenn es rein zufaellig an der Stelle 2047 sitzt. D.h. eventuell muesstest du das Skript zweimal laufen lassen, mit unterschiedlichen wrapping Breiten, und dann die Ausgaben vergleichen.

@marce:
So komplex ist das Perl Skript auch wieder nicht, dass man das nicht mal eben runterschreiben koennte, wenn man Zeit und Lust hat und haeufiger mit Perl arbeitet. Ich hab aber grad keins von beiden, und muesste mich auch erstmal wieder in Perl einarbeiten. ;)

mfg,
bytepool
 
@marce:
So komplex ist das Perl Skript auch wieder nicht, dass man das nicht mal eben runterschreiben koennte, wenn man Zeit und Lust hat und haeufiger mit Perl arbeitet. Ich hab aber grad keins von beiden, und muesste mich auch erstmal wieder in Perl einarbeiten. ;)
Das ist mir durchaus klar und geht mir auch so.

Mich k**** aber diese "hallo Jungs, liefert mir bitte mal die komplett-Lösung, ich habe nämlich keine Ahnung von gar nichts"-Einstellung mancher Leute an.

Ok, im konkreten Fall gibt es immerhin eine Grundlage, auf der man debuggen kann - es ist also keine von-0-an-Entwicklung...
 
Evtl. reicht es ja schon, grep durch perl zu ersetzen, etwa
Code:
find . -type f | xargs -n 25 perl -ne 'print "$ARGV: $_" if /61034709/i;'
oder
Code:
find . -type f -exec perl -ne 'print "$ARGV: $_" if /61034709/i;' {} \;
(ungetestet)
 
Hallo, ich habe es geschafft mit einem Perl Script danke für eure Hilfe nochmals.
 
Hallo, ich habe es geschafft mit einem Perl Script danke für eure Hilfe nochmals.
Für die Nachwelt könntest Du fairerweise noch Deine Lösung posten.....

Der nächste, der ein ähnliches Problem hat und die Such-Funktion im Forum benutz, könnte dann davon profitieren...
 
Hallo HBtux, du hast recht dann müssen die anderen nicht mehr suchen wenn Sie das gleiche Problem haben mit einer "alten" AIX Maschine.
Hoffe es hilft jemandem weiter.
Ich muss aber fairerweise sagen das das Programm nicht auf meinem Mist gewachsen ist sondern zusammen mit einem Freund von mir entwickelt wurde. Möchte mich nicht mit falschen Lobeeren schmücken.
Gruß Uli

#!/usr/bin/perl

use strict;
#use warnings;

my $DIRECTORY = "/spool/obj";
my $LOGFILE = "/home/check.log";

# open Logfile
open(LOG, ">>$LOGFILE") || die "can not open $LOGFILE: $!";


# open Directory
opendir (DH, $DIRECTORY) || die "no open: $!";

# loop over directory
foreach my $file (sort readdir DH)
{
# Use a regular expression to ignore files beginning with a period
next if ($file =~ m/^\./);
# only looking for files, skip directories
next unless (-f "$DIRECTORY/$file");

# process each file
open(FH, "<$DIRECTORY/$file") || die "can not open $file: $!";
my $line_count=0;
foreach my $line (<FH>)
{
$line_count++;
# search for pattern
if ($line =~ m/Suchtext/)
{
print "Pattern gefunden in Zeile $line_count in $file\n";
# LOG pattern
print LOG "Pattern gefunden in Zeile $line_count in $file\n";
}
}

close(FH);
}

# close Directory
closedir(DH);

# close Logfile
close(LOG);
 
Zurück
Oben