Ergebnis 1 bis 19 von 19
  1. #1
    Mitglied Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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):
    Code:
    find /var/mail/virtual/.*/[^push]*/(cur|new)/ -type f -exec rm {} \;
    Könnt ihr mir da weiterhelfen?


    Gruß,
    aXe²

  2. #2
    Open Source Kätzchen Avatar von HouseKatZe
    Registriert seit
    Apr 2010
    Ort
    /root
    Beiträge
    1.036
    NewsPresso
    10 (Fachgröße)

    Standard 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.

  3. #3
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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.

  4. #4
    (Threadentarter) Avatar von zilluss
    Registriert seit
    Aug 2007
    Beiträge
    1.059

    Standard 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 {} \;

  5. #5
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard Re: Reguläre Ausdrücke unter UNIX !?!?

    Zitat Zitat von zilluss Beitrag anzeigen
    find /var/mail/virtual/ -type f -regex .*/[^push]*/(cur|new)/ -exec rm {} \;
    Wenn ich das Kommando so übernehme, kommt:
    bash: syntax error near unexpected token `('

    Setze ich den regex-Teil in Anführungsstriche, findet er gar nichts.

  6. #6
    (Threadentarter) Avatar von zilluss
    Registriert seit
    Aug 2007
    Beiträge
    1.059

    Standard 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 {} \;

  7. #7
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard Re: Reguläre Ausdrücke unter UNIX !?!?

    Zitat Zitat von zilluss Beitrag anzeigen
    find /var/mail/virtual/ -type f -regex .*/\[^push\]*/\(cur|new\)/.* -exec rm {} \;
    Das sieht ziemlich gut aus, wenn ich es ausführe, kommt aber:
    bash: new)/.*: Datei oder Verzeichnis nicht gefunden

    Heißt also, die Anweisung ist korrekt, es werden aber keine Dateien gefunden?
    Kann nicht sein, weil die Ordner cur und new sind voll mit Dateien...

  8. #8
    Nerd

    Board:Crew

    Avatar von Kugelfisch23
    Registriert seit
    Oct 2007
    Ort
    Im Ozean
    Beiträge
    16.810

    Standard 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.

  9. #9
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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:

    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
    Beim 2ten random-Ordner möchte ich wie gesagt den Ordner push ausschließen.

  10. #10
    Nerd

    Board:Crew

    Avatar von Kugelfisch23
    Registriert seit
    Oct 2007
    Ort
    Im Ozean
    Beiträge
    16.810

    Standard 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:
    Code:
    perl -e '@files=`find /var/mail/virtual/ -type f`; for(@files) { print($_) if(m|^/var/mail/virtual/[^/]+/(?!push/)[^/]+/|) }'
    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.

  11. #11
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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²

  12. #12
    Nerd

    Board:Crew

    Avatar von Kugelfisch23
    Registriert seit
    Oct 2007
    Ort
    Im Ozean
    Beiträge
    16.810

    Standard 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.

  13. #13
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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:

    Code:
    perl -e '@files=`find /var/mail/virtual/ -type f`; for(@files) { print($_) if(m#^/var/mail/virtual/[^/]+/(?!push/)[^/]+/(cur|new)/#) }'
    Danke Kugelfisch23!
    Geändert von aXe² (10. 10. 2011 um 15:04 Uhr)

  14. #14
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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:

    Code:
    perl -e '@files=`find /var/mail/virtual/ -type f -mtime +14`; for(@files) { unlink($_) if(m#^/var/mail/virtual/[^/]+/(?!push/)[^/]+/(cur|new)/#) }'
    Habe das Gefühl, die unlink()-Methode wird nicht korrekt ausgeführt...

  15. #15
    Nerd

    Board:Crew

    Avatar von Kugelfisch23
    Registriert seit
    Oct 2007
    Ort
    Im Ozean
    Beiträge
    16.810

    Standard Re: Reguläre Ausdrücke unter UNIX !?!?

    Zitat Zitat von aXe² Beitrag anzeigen
    Habe das Gefühl, die unlink()-Methode wird nicht korrekt ausgeführt...
    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?

  16. #16
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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.

  17. #17
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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:

    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,
    Folgendes funktioniert:
    Code:
    rm 1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,
    Das selbe mit PERL funktioniert nicht:
    Code:
    perl -e unlink(1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,)
    Die unlink()-Method liefert ein Syntax-Error:
    bash: syntax error near unexpected token `('

    Dateiname in Anführungszeichen macht keinen Unterschied.

  18. #18
    Nerd

    Board:Crew

    Avatar von Kugelfisch23
    Registriert seit
    Oct 2007
    Ort
    Im Ozean
    Beiträge
    16.810

    Standard Re: Reguläre Ausdrücke unter UNIX !?!?

    Dies ist nicht das Problem, der Aufruf
    Code:
    perl -e unlink(1318172303.V811I738232fM173286.v220180178724751.yourvserver.net:2,)
    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 etwa
    Code:
    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 '@files=`find /var/mail/virtual/ -type f -mtime +14`; for(@files) { chomp; unlink($_) if(m#^/var/mail/virtual/[^/]+/(?!push/)[^/]+/(cur|new)/#) }'

  19. #19
    Mitglied

    (Threadstarter)

    Avatar von aXe²
    Registriert seit
    Apr 2006
    Beiträge
    277

    Standard 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)

  20.  
     
     

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •