# Jokerzeichen in der Bash

## manuels

Moin zusammen,

ich hab schon immer folgendes Problem mit Jokerzeichen z.B. loeschen.

Wenn ich die Dateien

```
/dir1/test1.txt

/dir2/test2.txt
```

habe und folgendes Kommando ausfuehre:

```
# pwd

/

# rm -R *.txt

```

Wird, falls keine Datei /*.txt existiert immer der Fehler ausgegeben

```
rm: cannot remove `*.txt': No such file or directory
```

Falls ich aber /test0.txt erstelle und dann den rm -R Befehl ausfuere, werden _alle_ Dateien geloescht.

Wie kann ich rm dazu ueberreden, dass er auch im ersten Fall die Dateien im Unterverzeichnis loescht?

Danke fuer Tipps

Manuel

PS: man koennte da mit find und xargs was basteln, ich find das aber fuer den Alltagsgebrauch zu umstaendlich

----------

## franzf

 *rm --help wrote:*   

> Per Voreinstellung entfernt rm keine Verzeichnisse. Bei Benutzung der Option
> 
> --recursive (-r oder -R) wird jedes aufgeführte Verzeichnisse inklusive seiner
> 
> Inhalte gelöscht.
> ...

 

Es werden also nur Verzeichnisse rekursiv entfernt, die du auch als Argument übergibts.

Ein rm -R *.txt wird also nur Dateien löschen, welche im aktuellen Verzeichnis liegen.

Über nicht vorhandene Dateien und die Fehlermeldungen lässt sich rm --help auch aus:

 *Quote:*   

>  -f, --force             nicht vorhandene Dateien ignorieren, keine Nachfragen
> 
>   -i                      vor jeder Entfernung nachfragen
> 
> 

 

Ich hoffe da war was für dich dabei  :Wink: 

Grüße

Franz

----------

## manuels

 *franzf wrote:*   

> Ein rm -R *.txt wird also nur Dateien löschen, welche im aktuellen Verzeichnis liegen.

 

Moment, das stimmt aber nach meinen Erfahrungen nicht.

```
       -r, -R, --recursive

              remove the contents of directories recursively

```

----------

## franzf

 *manuels wrote:*   

>  *franzf wrote:*   Ein rm -R *.txt wird also nur Dateien löschen, welche im aktuellen Verzeichnis liegen. 
> 
> Moment, das stimmt aber nach meinen Erfahrungen nicht.
> 
> ```
> ...

 

Ja, aber nur wenn du diese als Argument übergibst, also z.B.

```
rm -r dir/
```

Ein rm -r *.txt löscht dir dagegen nur die txt-Dateien im aktuellen Verzeichnis und lässt (trotz "-r"-Parameter) Verzeichnisse unangetastet. Hab ich zumindest beim Ausprobieren so beobachtet  :Wink: 

Also wohl am besten mit einem find rekursiv nach Dateien suchen und diese löschen.

----------

## Genone

Wenn du wirklich sämtlich Dateien, die auf .txt enden, aus einem bestimmten verzeichnis (inkl. aller Unterverzeichnisse) löschen willst reicht bash+rm nicht mehr aus, da wird find benötigt.

rm selber löscht einfach nur die übergebenen Dateinamen, und --recursive sorgt lediglich dafür, dass die Inhalte von angegebenen Verzeichnissen vorher (komplett) gelöscht werden (da Verzeichnisse nur gelöscht werden können wenn sie leer sind).

Hilft vielleicht sich in Erinnerung zu rufen dass Wildcards von Bash ausgewertet werden, nicht von den aufgerufenen Programmen, sprich bei einem 'rm -r *.txt' wertet Bash das *.txt aus und ruft dann rm mit den passenden Dateinamen auf (nur wenn halt kein Name passt wird *.txt übergeben, das für rm aber nur ein normaler Dateiname ist).

Im oben angeführten Beispiel übrigens würde anstelle von find auch folgendes gehen:

```
rm */*.txt
```

Funktioniert aber halt nur in direkten Unterverzeichnissen, nicht rekursiv.

----------

## misterjack

 *manuels wrote:*   

> 
> 
> Wenn ich die Dateien
> 
> ```
> ...

 

Bist du dir da sicher?

```

~/test $ ls -R

.:

dir1  dir2  text0.txt

./dir1:

text1.txt

./dir2:

text2.txt

~/test $ rm -R *.txt

~/test $ ls -R

.:

dir1  dir2

./dir1:

text1.txt

./dir2:

text2.txt

```

----------

## Necoro

die zsh bietet folgendes an: 

```
rm **/*.txt
```

 - wobei "**/" bedeutet "dieses und alle unterverzeichnisse". Vielleicht gibt es etwas ähnliches auch in der Bash

----------

## manuels

das find ich huebsch. Allerdings mag ich die zsh nicht.

Ich werd mal die bash manpage nach einem **-Equivalten durchforsten

----------

## mv

 *manuels wrote:*   

> das find ich huebsch. Allerdings mag ich die zsh nicht.

 

Warum nicht? (Die Frage ist ernst gemeint: Ich wüsste nämlich nichts, was die bash kann, was die zsh nicht besser kann).

 *Quote:*   

> Ich werd mal die bash manpage nach einem **-Equivalten durchforsten

 

Da kannst Du lange forsten. Für zsh gibt es noch ein paar Alternativen (eingebautes find...), bei bash musst Du auf das externe find zurückgreifen.

----------

## schmutzfinger

Es wurde zwar schon erwähnt das man find nutzen sollte aber wie das geht hat noch keiner geschrieben. Und jetzt hier so ne Glaubensfrage wie bash vs. zsh loszutreten ist auch nicht wirklich hilfreich.

```

find /dir/bla/ -name "*.txt" | xargs rm

```

----------

## mv

 *schmutzfinger wrote:*   

> Es wurde zwar schon erwähnt das man find nutzen sollte aber wie das geht hat noch keiner geschrieben.

 

Ist auch nicht nötig, da manuels ja extra betont hat, dass er das nicht will.

 *Quote:*   

> Und jetzt hier so ne Glaubensfrage wie bash vs. zsh loszutreten ist auch nicht wirklich hilfreich.

 

Doch, denn die zsh ist genau mit den Mitteln ausgestattet, solche Probleme zu lösen.

 *Quote:*   

> 
> 
> ```
> 
> find /dir/bla/ -name "*.txt" | xargs rm
> ...

 

Jau. Mach das als root. Und mach vorher noch 

```
mkdir "/dir/bla/ -rf /" && touch "/dir/bla/ -rf / .txt"
```

----------

## rc

OT

 *schmutzfinger wrote:*   

> 
> 
> find /dir/bla/ -name "*.txt" | xargs rm
> 
> 

 

ohne Pipe und xargs auch so:

```

find /dir/bla/ -name "*.txt" -exec rm {} \;

```

Ob das alles stimmt, was man machen will kann man ja mit sowas wie:

```

find /dir/bla/ -name "*.txt" -exec echo {} \;

```

vorher prüfen.

Das sollte auch die von mv erwähnte Problematik umgehen.

Edit: Als OT markiert, da ja find nicht verwendet werden soll.

Edit2: ganz so OT doch nicht, da diese Lösung nur mit "find" aber nicht mit xargs arbeitet.

Btw.: {} ist eine "Variable", die von find durch den jeweils gefundenen Dateinamen ersetzt wird.

Gruß,

rc

----------

## mv

 *rc wrote:*   

> 
> 
> ```
> 
> find /dir/bla/ -name "*.txt" -exec rm {} \;
> ...

 

Wenn, dann würde ich schon 

```
find /dir/bla -name "*.txt" -exec rm -- {} \+
```

 machen - da gibt es keinen Ärger, und es ist trotzdem schnell. Oder gleich die find-Option -delete benutzen, die aber leider nicht POSIX ist.

----------

## manuels

Noch so ein aehnlicher Fall:

Was mach ich mit 

```
rsync -av --exclude"*" --include mean /pfad .
```

falsch?

Ich moechte alle Dateien die "mean" heissen aus allen Unterverzeichnissen von /pfad kopieren, wobei die Unterverzeichnisse natuerlich auch erstellt werden sollen.

Danke fuer eure Tipps!

----------

## manuels

fuer die Akten: Das geht mit

```
rsync -av --include "*/" --include mean --exclude "*" /pfad .
```

----------

