Lidt hjælp til "find"
Hej.. Jeg har lige brug for lidt hjælp. Jeg er ved at lave et lille script der gør min dagligdag lidt nemmere.. Dog er jeg kommet lidt i stå.
Jeg vil gerne at "find" finder en fil og sletter mappen den er i.
Altså, leder jeg efter filen Blå.jpg, når "find" finder den skal den slette den mappe den er i.
Eks.
z4ndx@server:~$find . -type f -name "Blå.jpg" -print
./Kager/Blå.jpg
Så vil jeg gerne have at den sletter mappen "Kager"
Hvordan dælen gør jeg det ?
Jeg vil gerne at "find" finder en fil og sletter mappen den er i.
Altså, leder jeg efter filen Blå.jpg, når "find" finder den skal den slette den mappe den er i.
Eks.
z4ndx@server:~$find . -type f -name "Blå.jpg" -print
./Kager/Blå.jpg
Så vil jeg gerne have at den sletter mappen "Kager"
Hvordan dælen gør jeg det ?
Kommentarer24
Du kunne jo udskrive
Fx. (utestet)
find -name filnavn.txt -printf "%h\n" | xargs rm -rf
Du kom mig lige i
Følgende er afprøvet:
find . -type f -name "Blå.jpg" -printf %h | xargs rm -rf
Men pas altid på med kommandoer der indeholder rm -rf . Vær sikker på at du står det rigtige sted når du starter!
En god måde er først at
Jeg gør normalt sådan:
find . -type f -name "Blå.jpg" -print
Når jeg så har set at det er det ønskede... gentager med "-exec rm -rf {} \;" " krøllet paranteser backslash og semicolon
altså
find . -type f -name "Blå.jpg" -print -exec rm -rf {} \;
/Bengt
Dit råd med at printe
Dit råd med at printe første er godt og jeg bruger det selv. Dog er din kommando ikke korrekt i dette tilfælde, da det jo er mappen som indeholder filen der skal slettes, ikke bare selve filen.
Ideen kan sagtens videreføres til mit eksempel:
find . -type f -name "Blå.jpg" -printf %h | xargs echo rm -rf
Det ser ud til at virke fint
"-printf %h" gør at den vælger den øverste mappe, korrekt?
Jeg har dog ikke helt forstået brugen af xargs, hvorfor ? Hvorfor ikke bare bruge -exec rm -rf {} \; ?
Håber lidt der også er en
Jeg vil gerne:
if "resultatet af overstående find command er = 0" (den finder ingen filer med navnet Blå.jpg)
then
command
command
En der kan bikse lidt idet ?
if [[ "$(din find kommando)"
balblablaba
fi
men er du sikker på du ønsker == "0" ? og ikke "" ?
anyway.. sådan der er if syntaxen, for mere information, kør kommandoen "man test"
"-printf %h" gør at den
Nej, den vælger snarere den nederste mappe. Hvis strukturen er Mad/Dessert/Kager/Blå.jpg så returner den Mad/Dessert/Kager og sletter altså kun Kager og ikke Dessert mm.
Jeg har dog ikke helt forstået brugen af xargs, hvorfor ? Hvorfor ikke bare bruge -exec rm -rf {} \; ?
I princippet jo, men så får du ikke muligheden for at benytte mappenanvnet. rm -rf {} vil således kun slettet Blå.jpg (det efter -exec er uafhængig af -printf formatet!)
redeeman @ Hvad er
marlar @ Det er sådan set også godt nok da jeg formentligt ikke kommer længere ned end en mappe. Men hva nu hvis jeg gerne vil slette hele stien. Altså egenligt bare mappen Mad. Kan fixe noget der?
Men hva nu hvis jeg
Er du klar over omfanget af en sådan sletning? Alle mapper under Mad slettes hvis der et eller andet sted i hierakiet findes en fil der hedder Blå.jpg. Er du nu sikker på at det er det du ønsker? Hvis du starter kommandoen et forkert sted kan du i princippet slette hele harddisken!
det er på den måde
det er på den måde sammenligning af strenge, 0 er anderledes end tom.
marlar @ Hehe, så dropper
redeeman @ Hvad er forskellen?
redeeman @ Hvad er
Så simple spørgsmål er sgu nemmere (og mere lærerige) at afprøve i en terminal end at formulere i et forum.
Budskabet er at der er forskel på "0" (som er en streng, der består af karakteren '0') og "" (som er en tom streng). I dit tilfælde skal du naturligvis sammenligne med en tom streng.
Hele dit script kunne så følge en struktur a'la dette:
#!/bin/bash
count=0
for rmdir in `find -name filnvn.txt -printf %h`
do
echo "Nu sletter jeg biblioteket" $rmdir
count=$((count+1))
done
if [ $count -lt 1 ]; then
echo "HEY! Der blev ikke slettet noget!"
fi
Hvad er forskellen?
Nu
Nu er det ikke mig du spørger, men 0 er ikke det samme som "ingenting" => "".
Nul er numerisk og "" er alfanumerisk.
Måske kan du finde mere herfra - Unix Find Command Tutorial:
http://www.softpanorama.org/Tools/Find/find_mini_tutorial.shtml
Den omtaler også xargs
du kan selvfølgelig også
Synes det er vildt du kan
Jeg har lidt problemer med at få denne linje til at fungere.
find . -type d -iname "Kager" -printf %h | xargs rm -rvf
Den sletter ikke mappen som "Kager" er i. Hvorfor ?
find . -type d -iname
-printf %h skriver navnet på den mappe som Kager befinder sig hvilket er "." og denne pseudomappe kan ikke slettes. I stedet skal du bruge
find . -type d -iname "Kager" -print | xargs rm -rfv
Som tidligere nævnt er det en god ide at bruge echo i stedet for rm så du kan se hvad der sker. Prøv derfor disse to kommandoer og bemærk forskellen:
find . -type d -iname "Kager" -print | xargs echo
find . -type d -iname "Kager" -printf %h | xargs echo
Aaah jeg nu kan jeg se det
Hmm der er noget jeg ikke helt forstår.
Når jeg kører denne command, find . -type d -iname "Kager" -printf %h | xargs rm -rfv, fungere den som den skal. Den sletter den mappe "Kager" ligger i.
Men i mit script gør den ikke. Det er i dette sammenhæng.
read -p "Delete the folders contaning Kager? [y/n] " -n 1
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo
read -p "Are you sure? [y/n] " -n 1
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo
find . -type d -iname "Kager" -printf %h | xargs rm -rfv
echo " Done.."
echo
else
echo
echo "Skipping.."
fi
else
echo
echo "Skipping.."
fi
fi
Men i mit script gør
Og du er sikker på at scriptet når at afvikle kommandoen? Med andre ord: bliver der skrevet "Done.."?
EDIT: At dømme på det, du har kopieret ind, har jeg svært ved at se, hvad der sætter $REPLY...
Yeps. der bliver skrevet
Ingen bud ?..
Jeg har fundet problemet..
Det består faktisk af 2 ting.
Den første er at hvis den øverste mappe, "Kager" ligge i, har et space/mellemrum i navnet kan den ikke slette den.
Den anden er. Hvis der er 2 eller flere mapper med som har "Kager" mappen i sig, kan den heller ikke finde ud af det.
Hvordan løser jeg lige det ?
Den første er at hvis
Formentlig ved at indsætte nogle anførselstegn.
find . -type d -iname "Kager" -printf '"%h"'
#22: Den anden er. Hvis der er 2 eller flere mapper med som har "Kager" mappen i sig, kan den heller ikke finde ud af det.
Muligvis mangler der en newline:
find . -type d -iname "Kager" -printf '"%h"\n' | xargs rm -rfv
eller en null-karakter gør sikkert også jobbet, men så skal xargs kildes lidt under hagen:
find . -type d -iname "Kager" -printf '"%h"\0' | xargs --null rm -rfv
Men vigtigst af alt. Husk nu at debug ved at sætte echo ind lige efter xargs. Så er du meget bedre rustet til at finde ud af, hvad der går galt.
EDIT: rettede nogle tegn efter afprøvning
Super super super super
Troede virkelig ikke jeg ville få det løst.
find . -type d -iname "Kager" -printf '"%h"\0' | xargs --null rm -rfv
Virkede ikke.. Hverken på den ene eller på den anden...
Til gengæld virker den her fantastisk.
find . -type d -iname "Kager" -printf '"%h"\n' | xargs rm -rfv
Mange mange tak for alle jeres svar. Det er sku rart med noget prof hjælp når man selv hænger i vandskorpen. :P