-
09. 10. 2011, 18:30 #1
Reguläre Ausdrücke unter UNIX !?!?
Hi Leute,
ich suche einen regulären Ausdruck für den find-Befehl unter Unix.
Mein Ziel ist es alle Dateien in den Ordnern cur und new zu löschen.
Der Ordner unterhalb von "virtual" muss variabel sein und der darin liegende Ordner muss ungleich "push" sein. Hoffentlich verständlich?
Mein Ansatz (funktioniert so leider nicht):
Könnt ihr mir da weiterhelfen?Code:find /var/mail/virtual/.*/[^push]*/(cur|new)/ -type f -exec rm {} \;
Gruß,
aXe²
-
09. 10. 2011, 18:46 #2
Re: Reguläre Ausdrücke unter UNIX !?!?
Muss es unbedingt ein Befehl/Programm sein oder kannst du auch pipen? Dann würde ich das mit find, sed und xargs machen.
-
10. 10. 2011, 11:25 #3
Re: Reguläre Ausdrücke unter UNIX !?!?
Pipen ist auch iO!
Ich werde die Anweisungen in einen Cronjob packen, deshalb wäre es egal wieviele Befehle benutzt werden.
-
10. 10. 2011, 12:05 #4
Re: Reguläre Ausdrücke unter UNIX !?!?
Ich hab die manpage von find jetzt nur überflogen, aber ich glaube du kannst im Suchpfad (erster Parameter) noch keine regex benutzen. Ich kanns nicht testen, aber das hier ist eher das was du brauchst.
find /var/mail/virtual/ -type f -regex .*/[^push]*/(cur|new)/ -exec rm {} \;
-
10. 10. 2011, 12:30 #5
-
10. 10. 2011, 12:48 #6
Re: Reguläre Ausdrücke unter UNIX !?!?
Ach... welche Zeichen man escapen muss und welche nicht scheint auch überall anders und willkürlich zu sein
anscheinend muss man () und [] escapen, da er sonst nach diesen Zeichen im Pfad sucht. Am Ende muss ausserdem sollte man sicherheitshalber ein .* am ende einfügen weil -regex den kompletten pfad matcht und ich keine ahnung habe wie find das handelt. Insgesamt sieht das ganze dann so aus.
find /var/mail/virtual/ -type f -regex .*/\[^push\]*/\(cur|new\)/.* -exec rm {} \;
-
10. 10. 2011, 13:05 #7
Re: Reguläre Ausdrücke unter UNIX !?!?
-
10. 10. 2011, 13:28 #8
Re: Reguläre Ausdrücke unter UNIX !?!?
Setze den regulären Ausdruck in einfache (oder ggf. doppelte, sofern du die Variablenexpansion benötigen solltest) Anführungszeichen (i.e. ' oder ggf. "), um zu verhindern, dass die bash darin enthaltene Sonderzeichenfolgen oder Escape-Sequenzen auswertet. In deinem Fall werden insbesondere die *-Zeichen als Wildcards durch die bash ausgewertet, was sicherlich nicht das von dir erhoffte Verhalten ist. Wenn find daraufhin keine Treffer liefert, ist der reguläre Ausdruck inkorrekt bzw. für deine Dateinamen unpassend.
Nachtrag: Dein regulärer Ausdruck ist bei genauerer Betrachtung nicht korrekt - das Konstrukt [^foobar] ist ein häufiger Fehler. [^...] sorgt dafür, dass die angegebenen Zeichen an dieser Stelle nicht auftreten dürfen, nicht das angegebene Wort. Das gesamte Konstrukt steht für ein einziges Zeichen. Für dein Vorhaben benötigst du negative lookahead- oder lookbehind-Assertions, die jedoch finds RegEx-Engine nicht implementiert. Aus diesem Grund wird Piping (oder ein simples Perl-Skript) wohl unumgänglich sein.Geändert von Kugelfisch23 (10. 10. 2011 um 13:45 Uhr) Grund: Nachtrag hinzugefügt.
-
10. 10. 2011, 13:42 #9
Re: Reguläre Ausdrücke unter UNIX !?!?
@Kugelfisch: OK, dann ist der reguläre Ausdruck wohl unpassend.
Anführungszeichen liefern kein Error, aber auch kein Ergebnis.
Hier mal ein Ausschnitt aus meiner Verzeichnisstruktur:
Beim 2ten random-Ordner möchte ich wie gesagt den Ordner push ausschließen.Code:/var/mail/virtual/random78347/random123/cur /var/mail/virtual/random238923/random123/new /var/mail/virtual/random2345/random345/cur /var/mail/virtual/random348/random345/new /var/mail/virtual/random2345/random234/cur /var/mail/virtual/random23451/random3623/new
-
10. 10. 2011, 13:57 #10
Re: Reguläre Ausdrücke unter UNIX !?!?
Mein Nachtrag im vorherigen Beitrag hat sich wohl mit deinem Beitrag überschnitten. Möglich wäre dein Vorhaben (sofern ich die Bedingungen korrekt interpretiert habe) etwa mit dem folgenden Perl-Einzeiler:
Dieser listet die passenden Dateipfade lediglich auf. Ist das Ergebnis korrekt, kannst du den print()- durch einen unlink()-Aufruf ersetzen, um die Dateien tatsächlich löschen zu lassen.Code:perl -e '@files=`find /var/mail/virtual/ -type f`; for(@files) { print($_) if(m|^/var/mail/virtual/[^/]+/(?!push/)[^/]+/|) }'
-
10. 10. 2011, 14:15 #11
Re: Reguläre Ausdrücke unter UNIX !?!?
OK, danke für die Info zur RegEx-Engine vom find-Befehl, wieder was dazu gelernt!

Das PERL-Script sieht sehr gut aus und funktioniert!
Gut, dass du erst die print-Methode reingepackt hast, sonst hätte ich beim schnellen Copy&Paste direkt alles gelöscht, was ich jetzt noch nicht möchte.
Habe versucht das ganze noch auf die o.g. Ordner zu beschränken,
bekomme aber leider nur Syntax-Errors.
Kannst du mir noch ein Tipp geben,
wie ich (cur|new) genau an den Pfad anhängen muss?
Gruß,
aXe²
-
10. 10. 2011, 14:31 #12
Re: Reguläre Ausdrücke unter UNIX !?!?
Hänge am Ende des regulären Ausdrucks (vor dem schliessenden Begrenzer-|) den Bestandteil (cur\|new)/ an. Die Maskierung von | ist notwendig, da ich dieses Zeichen in meinem Beispiel als Begrenzer genutzt habe. Selbstverständlich könntest du alternativ die Begrenzer-Zeichen durch nicht im Ausdruck enthaltene (z.B. ~) ersetzen, dann würde die Maskierung entfallen.
-
10. 10. 2011, 14:41 #13
Re: Reguläre Ausdrücke unter UNIX !?!?
OK, dann war das identische Begrenzer-Zeichen die Ursache der Syntax-Fehler.
Hier also das funktionierende PERL-Kommando:
Danke Kugelfisch23!Code:perl -e '@files=`find /var/mail/virtual/ -type f`; for(@files) { print($_) if(m#^/var/mail/virtual/[^/]+/(?!push/)[^/]+/(cur|new)/#) }'
Geändert von aXe² (10. 10. 2011 um 15:04 Uhr)
-
12. 10. 2011, 14:22 #14
Re: Reguläre Ausdrücke unter UNIX !?!?
Ich muss nochmal nachhaken:
Ich möchte das PERL-Script als Cronjob einrichten, sodass täglich alle Dateien, die älter als 14 Tage sind gelöscht werden.
Ich habe das mit dem Parameter -mtime für den find-Befehl gelöst.
Leider werden mit folgendem Kommando aber keine Dateien gelöscht:
Habe das Gefühl, die unlink()-Methode wird nicht korrekt ausgeführt...Code:perl -e '@files=`find /var/mail/virtual/ -type f -mtime +14`; for(@files) { unlink($_) if(m#^/var/mail/virtual/[^/]+/(?!push/)[^/]+/(cur|new)/#) }'
-
12. 10. 2011, 14:55 #15
Re: Reguläre Ausdrücke unter UNIX !?!?
Das kannst du leicht überprüfen, indem du den unlink- durch einen print-Aufruf ersetzt und die Ausgabe überprüfst. Bedenke auch, dass das Verhalten von find bei Angabe eines Werts ohne Einheit nicht exakt demjenigen bei Angabe der Einheit d (Tage) entspricht.
Wenn die auf den regulären Ausdruck passenden (und ausgegebenen) Dateien nicht gelöscht werden, stelle sicher, dass das Perl-Skript unter einem Benutzerkonto ausgeführt wird, das über Schreibzugriff auf die fraglichen Verzeichnisse verfügt. Versuche, das Skript in der Shell mit diesem Benutzerkonto auszuführen. Zeigt es dann die erwartete Wirkung?
-
12. 10. 2011, 15:11 #16
Re: Reguläre Ausdrücke unter UNIX !?!?
Ok:
Erst print(), dann unlink(), dann nochmal print() --> die Anzahl an Dateien bleibt gleich...
Ich bin als root per SSH eingeloggt, also volle Rechte.
-
13. 10. 2011, 11:25 #17
Re: Reguläre Ausdrücke unter UNIX !?!?
Kann es sein, dass die Dateien nicht gelöscht werden könnnen, weil die Dateinamen zu speziell sind?
Hier als Beispiel mal der Ordnerinhalt (ls -l) von einem Ordner:
Folgendes funktioniert:Code:ls -l insgesamt 12 -rw------- 1 vmail mail 979 9. Okt 16:58 1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2, -rw------- 1 vmail mail 1194 9. Okt 16:59 1318172354.V811I7382331M549676.v220180178724751.yourvserver.net:2, -rw------- 1 vmail mail 967 9. Okt 17:04 1318172665.V811I7382335M814829.v220180178724751.yourvserver.net:2,
Das selbe mit PERL funktioniert nicht:Code:rm 1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,
Die unlink()-Method liefert ein Syntax-Error:Code:perl -e unlink(1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,)
bash: syntax error near unexpected token `('
Dateiname in Anführungszeichen macht keinen Unterschied.
-
13. 10. 2011, 12:37 #18
Re: Reguläre Ausdrücke unter UNIX !?!?
Dies ist nicht das Problem, der Aufruf
ist nicht korrekt. Bedenke, dass du sowohl den Perl-Code in Anführungszeichen setzen (oder alle in der Shell relevanten Sonderzeichen maskieren) musst, damit er als einzelnes Argument an perl übergeben wird, als auch den Dateinamen innerhalb des Perl-Codes in Form eines String-Literals angeben musst. Passend dazu wäre etwaCode:perl -e unlink(1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,)
Allerdings enthält mein Beispielcode einen Fehler: Die Zeilen-Trennzeichen, die sich am Ende jeder Zeile (die jeweils einen Dateinamen enthält) des Outputs von find befinden, werden nicht entfernt. Deshalb sind die Zeilen bei der Ausgabe mittels print() auch durch Zeilentrennzeichen getrennt. unlink() wird hingegen keine Dateien des entsprechenden Namens finden. Korrektur:Code:perl -e "unlink('1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,')"
Code:perl -e '@files=`find /var/mail/virtual/ -type f -mtime +14`; for(@files) { chomp; unlink($_) if(m#^/var/mail/virtual/[^/]+/(?!push/)[^/]+/(cur|new)/#) }'
-
13. 10. 2011, 13:00 #19
Re: Reguläre Ausdrücke unter UNIX !?!?
Wow, danke Kugelfisch23 - sowohl der einzelne Befehl als auch das Mini-Script funktionieren!

Auf die Sache mit dem Zeilenumbruch wäre ich nie gekommen,
dachte vielmehr dass die Shell die Ausgabe automatisch so formatiert,
um das Lesen zu vereinfachen...
Werde morgen berichten ob der CronJob auch geklappt hat.
Edit: Cronjob klappt!
Geändert von aXe² (14. 10. 2011 um 14:01 Uhr)
-


Zitieren


mehr lesen...







Microsoft: Windows 8 OEM...
Heute, 14:12 in gulli:news