bash pattern matching

Post Reply
Message
Author
Chupi

bash pattern matching

#1 Post by Chupi »

hi
kann mir jemand sagen, wie ich folgendes anstelle?
nehmen wir an, ich hab folgende log-files:

log123.456.789.AZT.log
log172.333.112.AZT.log
log340.112.236.AZT.log

nun will ich alle, ausser dem, dass eine 456 in seinem namen hat löschen. (456 hintereinander!)

bash$ rm log*[!456]* --> klappt nicht
bash$ rm log*!(456)* --> auch nicht

klar kann man das mit find oder awk usw. machen, aber mich nimmts wunder, obs auch mit der bash funktioniert.
jemand ne ahnung?

User avatar
max
Posts: 806
Joined: 14. May 2000 12:55
Location: Ruhrpott

Re: bash pattern matching

#2 Post by max »

habe da auch immer meine Problemchen mit RegEx in der bash *Kriegsfuß*
aber sollte es nicht .* statt * und ![456] statt [!456] heißen?
Max

chupi

Re: bash pattern matching

#3 Post by chupi »

> aber sollte es nicht .* statt * und ![456] statt [!456] heißen?
> Max

ne...überhaupt nicht

Michael

Re: bash pattern matching

#4 Post by Michael »

for i in `ls /pfad/* | grep -v 456` ; do rm $i; done

Cheers

Michael

Jochen

Re: bash pattern matching

#5 Post by Jochen »

Du warst aber schon nah dran.

log*[!456]* kann nicht funktionieren, da die eckigen Klammern für <b>genau ein Zeichen</b> stehen, welches eines von denen in der Zeichenmenge sein darf.

log*!(456)* kommt fast hin, aber das erweiterte Globbing muss erst eingeschaltet werden. Ausserdem muss man dann mit "*" vorsichtig sein, da das ja für eine beliebige Folge beliebiger Zeichen steht - also auch "456"! So funktioniert's: <blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">shopt -s extglob # Extended Globbing einschalten, wird nur einmal benötigt
ls log*.!(456).*
</font><hr></pre></blockquote>

Jochen

chupi

Re: bash pattern matching

#6 Post by chupi »

@michael: ja so funktionierts...ist mir aber zu umständlich. das muss doch einfacher gehen ja?

@jochen: hast du das getestet? ich denke nicht!

Michael

Re: bash pattern matching

#7 Post by Michael »

aus ner Doku:

snip
----
Die eckige Klammer wird ersetzt durch eines der in der Klammer stehenden Zeichen. Auch ein Bereich ist möglich, z. B. [a-k] = [abcdefghijk]. Beispiel: "a[bcd]" wird ersetzt durch "ab", "ac" und "ad". Soll das Minuszeichen selbst in die Zeichenmenge aufgenommen werden, muß es an erster Stelle stehen (gleich nach der öffnenden Klammer).
----
snap

durch eines der
*****

So wie du das geplant hast, wirds nix.

Cheers

Michael

Jochen

Re: bash pattern matching

#8 Post by Jochen »

Hoppala. Selbstverständlich habe ich das getestet. Das Feature des Extended Globbings benutze ich eher selten, so dass ich vorsichtshalber solche Sachen immer mal schnell anteste. Also wollte ich gerade mal (ganz entrüstet) per Cut'n'Paste aus der Konsole pasten, wie das bei mir funktioniert. Und sieh mal an - es geht nicht?!? Das Problem war dann auch schnell gefunden: Ich hatte die Dateinamen von Dir nicht 1:1 übernommen. Das !() ist in Kombination mit dem * tückisch... Mea culpa. Wenn <i>irgendwo</i> im Dateinamen zwischen zwei Punkten eine Zeichenfolge steht, die nicht "456" ist, dann ist das für die bash OK, weil die Sterne vorne und hinten alles andere abdecken. Man könnte es aber so schreiben:<pre>ls log!(456).!(456).!(456).AZT.log</pre>Und <b>das</b> funktioniert - ehrlich! <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">

Michael hat einen Hang zum Zuviel-Selber-Machen: Die for-Schleife, um dem rm-Kommando jede Datei einzeln vorzuwerfen, ist überflüssig:<pre>rm `ls /pfad/* | grep -v 456`</pre>tut's auch. Dafür hat seine erste Lösung aber den Vorteil, dass sie funktioniert (im Gegensatz zu meiner ersten Version). <img src="http://www.pl-forum.de/UltraBoard/Images/Wilk.gif" border="0" align="middle">

Jochen

Post Reply