PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : die bash, find und die wildcards



toto
20.01.2004, 23:25
hi...
ich bin neu an der bash, deswegen habt rücksicht :D

mein problem ist folgendes:
ich habe ein kleines skript, indem ich die ausgabe eines find-kommandos durchgehe und aktionen veranlasse.
das kommandozeilenargument ist dabei das muster, mit dem "find" sucht.

konkret (skript rmrec)
----------------
#!/bin/bash
pattern=$1

for i in `find -name $pattern`; do
rm -f $i
done
-----------------

das "find" wie es oben steht funktioniert an der kommandozeile selbst wunderbar. mir ist es wichtig, die unterverzeichnisse auch mitzunehmen, deswegen "find". das problem ist das sichern des kommandozeilenarguments in "$1",
wenn die wildcard "*" benutzt wird, etwa wenn ich das skript aufrufe mit "rmrec wurst*"
wenn ich $1 ausgebe, ist $1 lediglich das alphabetisch erste element aller elemente, bspw wäre es "wurstbrot", auch wenn es noch die dateien "wurstkoffer" und "wurststulle" gibt. :D
der rest wird gar nicht mitgenommen !
wie kann ich das direkte auswerten der wildcard verhindern ?

habs hiermit probiert:
for i in ''`find -name '*''$pattern''*'`;do...
funzt nicht !
danke für die hilfe !
chao

toto
20.01.2004, 23:34
sorry hatte was vergessen:

wenn ich das skript mit bspw
"rmrec 'wurst*' " aufrufe findet "find" tatsächlich alle einträge...aber geht nicht in die subdirectories..!!!

weiss jemand warum und wie man dem abhelfen kann ?

dange
toto

rup
21.01.2004, 00:31
So sollte es gehen:



#!/bin/bash

find . -name "$1" -exec rm -f {} \;

toto
21.01.2004, 00:49
hallo rup
danke erstmal !
diese zeile produziert allerdings genau das gleiche problem: "find" findet nur das alphabetisch nächste Element , löscht also nach dem "element1" nur das "element2" usw.

wieso is das eigentlich so ? kann mir das jemand kurz erklären ?
danke
toto

tr0nix
21.01.2004, 07:00
Ich vestehe dein Problem nicht ganz. Wie meinst du das mit "Alphabetisch"? Wie willst dus denn?

BTW. ich wuerde das nicht als Script machen sondern selbst eintippen. Ist IMHO zu heiss wenn dus als root ausfuehrst!

toto
21.01.2004, 10:04
hallo !

mit alphabetisch meine ich : das element was im alphabet als nächstes kommen würde- nach "element2" kommt "element3" und bspw nicht "element7".
das ist allerdings nicht das problem !
das problem ist, das wenn man das skript ausführt, dieses nur _ein_ Element löscht.
z.B:

es existieren die Dateien

elt1, elt2, elt3, elt4

das skript würde ausgeführt mit dem argument "el*" nur "elt1" löschen, allerdings nicht die übrigen dateien, obwohl sie das suchmuster "matchen".

warum ?
rätselt
toto

tr0nix
21.01.2004, 12:45
Mh ich koennts mir denken!

Mach mal ein echo auf $1 im Script. Moeglicherweise macht die Shell bereits eine Substitution auf die Wildcard (sollte ja eigentlich durch die ' vermieden werden, aber mach trotzdem mal).

Greetz
Joel

toto
21.01.2004, 13:24
hi tr0nix...
ja, das ist auch so...das habe ich bereits getestet, die shell wertet schon das $1 aus !
wie kann man das verhindern, ausser das argument in ' hochkommata ' zu setzen ?

bzw. wenn man soweit ist, geht "find" nur im aktuellen verzeichnis umher... und nicht in den unterverzeichnissen...woran liegt das ?

danke
toto

rup
21.01.2004, 18:56
Wie man das verhindern kann faellt mir gerade nicht ein, bin bisher nie auf das Problem gestossen. Bis zu einer gewissen Anzahl von Argumenten hilft folgendes:



#!/bin/bash

while [ $# -gt 0 ]
do
rm -f $1
shift
done

Yuuhi
21.01.2004, 19:21
hi tr0nix...
ja, das ist auch so...das habe ich bereits getestet, die shell wertet schon das $1 aus !
wie kann man das verhindern, ausser das argument in ' hochkommata ' zu setzen ?

bzw. wenn man soweit ist, geht "find" nur im aktuellen verzeichnis umher... und nicht in den unterverzeichnissen...woran liegt das ?


Tjoar, hast wohl nur die 2 Moeglichkeiten das Argument entweder in ' ' zu setzen oder eventuelle wildcards mit \ zu escapen, wogegen eigentlich auch nichts sprechen sollte, oder?

Alternativ kann es auch noch sein, dass deine Shell vielleicht noch die Moeglichkeit bietet das globbing abzuschalten.

[0]benni@sehanine:~/src/shell% ls tm*
tmp
[0]benni@sehanine:~/src/shell% setopt noglob
[0]benni@sehanine:~/src/shell% ls tm*
ls: tm*: No such file or directory

Das koenntest du aber natuerlich nicht im Script machen, sondern nur in der Shell, wo du es aufrufst.

find sollte uebrigens eigentlich auch in den Unterverzeichnissen suchen, bei welchem konkreten Aufruf hast du das Problem?

mfg,

Yuuhi

toto
26.01.2004, 10:30
hi yuuhi,
danke für den beitrag.

der find-aufruf funktioniert, wenn ich ihn von der shell aus aufrufe; er funktioniert auch, wenn ich ihn im skript aufrufe , aber nicht, wenn ich ihm das kommandozeilenargument übergebe, sprich $1.
setze ich $1 im aufruf in hochkommata, findet "find" zumindest mehr als das nächste element (siehe oben).
aber dann geht "find" stumpf _nicht_ in die unterverzeichnisse! ich finde das sehr merkwürdig !
kennt noch jemand das problem ?

soweit deine frage ?
mfG
toto

Yuuhi
28.01.2004, 21:11
Was ich gerne gehabt haette, waere genau das Skript mit dem du aktuell das Problem hast. Etwas, dass ich hier selber testen kann, um das Problem nachzuvollziehen.

Ich kann natuerlich meine Glaskugel rausholen und versuchen zu erraten was das Problem ist.

Experementieren wir halt mal ein wenig mit find, um dein Problem zu verstehen...
Nehmen wir dazu dieses Skript, das genau das von dir beschriebene Verhalten hat:

#!/bin/bash

pattern=$1
find $pattern


[0]benni@sehanine:~/texte% ./blubb.sh a*
adsl

[0]benni@sehanine:~/texte% ./blubb.sh "a*"
adsl
ailesgrises.pdf
aoapdf.tar.gz

Das ist genau das von dir beschriebene Verhalten. Nur woran liegt das?
Beim ersten Aufruf loest die Shell die Wildcard sofort auf. Damit landet in $1 nur der _erste Dateiname_ und nicht das Pattern. Damit kommt bei find nur der Dateiname an und wird auch gefunden.

Beim zweiten Mal ueberlebt es das Pattern immerhin bis in das Skript... es wird aber vor dem Aufruf von find aufgeloest. find datei1 datei2 datei3 findet dann genau die 3 Dateien und geht nicht in Unterverzeichnisse.
Korrekt sollte das ganze also so aussehen:

#!/bin/sh

pattern=$1 (wenn man das denn unbedingt will...)
find . -name "$pattern"

Damit sollte es dann keine solchen Probleme geben.

Mata ne,

Yuuhi