[find] lege directories verwijderen

Pagina: 1
Acties:
  • 207 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17-06 20:07

Robtimus

me Robtimus no like you

Topicstarter
Ik ben bezig met een programma'tje, waarin ik lege directories moet verwijderen.
Nu kan ik al die directories vinden mbv "find <DIR> -type d -empty", maar dan komt het verwijderen.

Ik heb natuurlijk "find <DIR> -type d -empty -exec rmdir \{\} \;" al geprobeerd, maar dat heeft een probleem: ik krijg voor elke directory een melding
find: <LEGE DIR>: No such file or directory
De directory wordt wel goed verwijderd.

Ik kan ook niet de inhoud in een VAR stoppen en dan met for over die VAR heengaan, want dat gaat niet goed met namen met spaties erin:
code:
1
2
3
4
5
6
7
8
9
10
11
12
for i in $VAR
do
    rmdir $i
    # $i zal een split zijn als er een spatie in de naam staat
    # dus ipv "test dir" 2 iteraties met de ene test en de ander dir
done

for i in "$VAR"
do
    rmdir $i
    # $i is de volledige inhoud van $VAR; het probleem wordt naar rmdir verschoven
done
Iemand een oplossing die werkt (zoals de eerste) maar geen nare foutmeldingen geeft?

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

  • Tony Vroon
  • Registratie: Juni 1999
  • Laatst online: 13-06-2020

Tony Vroon

Werkt nu ergens anders

| xargs rmdir

xargs is een erg handig progje, het verandert de lijst met opties in een rij argumenten, gescheiden met spaties. Test het even droog met een echo oid.

[ Voor 8% gewijzigd door Tony Vroon op 06-05-2004 15:39 ]

"Wie is deesen figuur, hier ten topic aangheduidt als 'hij', wiens mededelinghe soo eenen consternatie weet te ontluycken :? " -- dion_b


Acties:
  • 0 Henk 'm!

  • sebas
  • Registratie: April 2000
  • Laatst online: 27-01 12:02
Hoezo vind je de foutmelding naar? Ik zou niet weten wat ermee mis is, of wat negatieve gevolgen zouden kunnen zijn ... (Het is trouwens geen foutmelding, maar een warning.)

Everyone complains of his memory, no one of his judgement.


Acties:
  • 0 Henk 'm!

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 21-05 20:48

odysseus

Debian GNU/Linux Sid

Werkt het volgende misschien wel? Ik denk dat jouw -exec ervoor zorgt dat het direct bij het vinden wordt uitgevoerd en dan staat find waarschijnlijk nog in die directory, die vervolgens verwijderd wordt...dan zit find dus in een niet bestaande directory en komt er een fout. Dat is overigens een wilde speculatie, er kan ook wel wat anders aan de hand zijn :).
code:
1
find <DIR> -type d -empty | xargs rmdir

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17-06 20:07

Robtimus

me Robtimus no like you

Topicstarter
sebas schreef op 06 mei 2004 @ 15:40:
Hoezo vind je de foutmelding naar? Ik zou niet weten wat ermee mis is, of wat negatieve gevolgen zouden kunnen zijn ... (Het is trouwens geen foutmelding, maar een warning.)
Het kan inderdaad geen kwaad, maar het is natuurlijk niet netjes dat je voor elke lege directory (ik doe het ook nog eens recursief, dus het kan behoorlijk veel worden) die melding krijgt.

Ik had trouwens ook al geprobeerd stderr te redirecten naar /dev/null, maar afhankelijk van parameters wil ik rmdir verbose uitvoeren; die verbose output zit met find ook in stderr.
odysseus schreef op 06 mei 2004 @ 15:40:
Werkt het volgende misschien wel? Ik denk dat jouw -exec ervoor zorgt dat het direct bij het vinden wordt uitgevoerd en dan staat find waarschijnlijk nog in die directory, die vervolgens verwijderd wordt...dan zit find dus in een niet bestaande directory en komt er een fout. Dat is overigens een wilde speculatie, er kan ook wel wat anders aan de hand zijn :).
code:
1
find <DIR> -type d -empty | xargs rmdir
Ik dacht zelf ook al dat dat waarschijnlijk gebeurd; hij past de lijst van directories natuurlijk nog niet aan.

xargs rmdir werkt trouwens niet: die scheidt ook directories met spaties erin (de grote boosdoener):
[ice@x projects]$ find Ice\ Man/ -type d -empty | xargs rmdir
rmdir: `Ice': No such file or directory
rmdir: `Man/': No such file or directory

[ Voor 6% gewijzigd door Robtimus op 06-05-2004 15:49 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

Anoniem: 13700

IceManX schreef op 06 mei 2004 @ 15:47:
xargs rmdir werkt trouwens niet: die scheidt ook directories met spaties erin (de grote boosdoener):
Op deze manier slikt xargs wel spaties:
code:
1
find <DIR> -type d -empty | xargs -i rmdir '{}'

Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17-06 20:07

Robtimus

me Robtimus no like you

Topicstarter
Anoniem: 13700 schreef op 06 mei 2004 @ 16:08:
[...]


Op deze manier slikt xargs wel spaties:
code:
1
find <DIR> -type d -empty | xargs -i rmdir '{}'
_/-\o_ _/-\o_ _/-\o_

Ik dank u hartelijk :)

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

  • easydisk
  • Registratie: Februari 2000
  • Laatst online: 13:47
Of even de deler van spatie op enter zetten, zie het voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
IFS="
"

for part in $(ls *.mp3);
do
    echo " $part ";
    mpg123 -w nu.wav "$part"
    lame -b 256 nu.wav "$part"
done;
rm nu.wav

Als er geen IFS als enter gedifineerd werd zou het inderdaad op spatie gedeeld worden en mp3 bestanden met een spatie zouden dus de mist ingaan.

[ Voor 8% gewijzigd door easydisk op 06-05-2004 16:34 ]


Acties:
  • 0 Henk 'm!

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05 20:45
-exec rm {}\; had volgens mij ook gewerkt

Acties:
  • 0 Henk 'm!

  • Wilke
  • Registratie: December 2000
  • Laatst online: 14:22
Als je problemen hebt met spaties en andere rare tekens, check dan ook de optie '-print0' van find en '--null' ofwel '-0' van xargs eens :)

Acties:
  • 0 Henk 'm!

Anoniem: 13700

Ik ben nu thuis en heb het topic nog eens goed doorgelezen. De TS zegt dat hij de directories recursief wil doorlopen, dat had ik ff gemist. Dat impliceert dat oplossingen met xargs niet gaan werken, want de directories worden op die manier eerst doorlopen en dan pas verwijderd, hetgeen betekent dat directories die alleen uit lege subdirectories bestaan niet verwijderd worden.

Het probleem met de foutmeldingen wordt veroorzaakt doordat find standaard een breedte-eerst recursief algoritme toepast. De oplossing is dus simpel: laat find een diepte-eerst recursie toepassen.
code:
1
find <DIR> -mindepth 1 -depth -type d -empty -exec rmdir '{}' \;

Ik heb -mindepth 1 toegevoegd omdat <DIR> zelf anders ook gewist wordt indien ze leeg is.

[ Voor 10% gewijzigd door Anoniem: 13700 op 06-05-2004 18:21 . Reden: typo's ]


Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17-06 20:07

Robtimus

me Robtimus no like you

Topicstarter
Sir Isaac schreef op 06 mei 2004 @ 17:53:
-exec rm {}\; had volgens mij ook gewerkt
Nee, want het ging om directories, niet om bestanden. En rmdir had ik al geprobeerd, dat werkt maar levert waarschuwingen/foutmeldingen.
Anoniem: 13700 schreef op 06 mei 2004 @ 18:12:
Ik ben nu thuis en heb het topic nog eens goed doorgelezen. De TS zegt dat hij de directories recursief wil doorlopen, dat had ik ff gemist. Dat impliceert dat oplossingen met xargs niet gaan werken, want de directories worden op die manier eerst doorlopen en dan pas verwijderd, hetgeen betekent dat directories die alleen uit lege subdirectories bestaan niet verwijderd worden.

Het probleem met de foutmeldingen wordt veroorzaakt doordat find standaard een breedte-eerst recursief algoritme toepast. De oplossing is dus simpel: laat find een diepte-eerst recursie toepassen.
code:
1
find <DIR> -mindepth 1 -depth -type d -empty -exec rmdir '{}' \;

Ik heb -mindepth 1 toegevoegd omdat <DIR> zelf anders ook gewist wordt indien ze leeg is.
Nou niet helemaal.

Het recursief deed ik tot nu toe nog zelf:
zolang de enige lege directory niet de rootdir is, verwijder alle lege directories. Ik dacht nml dat find slechts 1x alles afzoekt, en dat is niet de bedoeling. Een directory hoeft de eerste keer niet leeg te zijn, maar kan dat wel zijn nadat al zijn subdirectories zijn verwijderd.

xargs werkt dus wel. Misschien niet zo efficient (2x find per loop), maar het werkt wel.


Net even jouw code getest: alles wat ik wil in 1 commando! Thx!

[ Voor 4% gewijzigd door Robtimus op 06-05-2004 18:46 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

Anoniem: 13700

IceManX schreef op 06 mei 2004 @ 18:35:
Ik dacht nml dat find slechts 1x alles afzoekt, en dat is niet de bedoeling.
find doorloopt altijd maar 1x de directory tree en doorzoekt hem 2x ; de vraag is alleen hoe ;)

Standaard bewerkt find eerst de root, daarna de subdirectories en dan de subdirectories van de subdirectories, enz.; dit heet breedte-eerst recursie. Door de -depth parameter bewerkt find eerst de diepste subdirectories, daarna de parent-directories van die directories, enz. tot uiteindelijk de root bereikt wordt, precies andersom dus; dit heet diepte-eerst recursie.

Doordat find -depth eerst de subdirectories doorloopt en wist is het dus mogelijk dat de root leeg is tegen de tijd dat find daar aankomt (en je geen foutmeldingen krijgt).
Pagina: 1