Puncte:6

Comanda mea `find` din script nu găsește fișiere și directoare cu spații în numele lor

drapel pr

Cu ceva timp în urmă am scris un script care mută fișiere și directoare din Descărcări la .Descărcări dacă sunt mai vechi de 3 zile și ștergeți-le din acest director după 30 de zile. Funcționează bine, dar numai pentru fișierele fără spații.

Am investigat și am constatat că găsi comanda pe care o folosesc în script nu funcționează așa cum mă așteptam pentru orice fișier sau director cu spații în numele lor.

Iată ce găsi face:

găsiți ieșirea comenzii

Mă așteptam să văd găsi comanda găsiți și fișierele cu spații.

Iată scenariul:

#! /bin/bash
# set -x
export DISPLAY=:0.0

# true - șterge, altfel - muta
function process(){
    if [ "$2" = "ȘTERGERE" ]; atunci
        rm -r "$1" && notify-send "$3 $1 șters!"
    altfel
    mv „$1” „../.Downloads/$1” && notify-send „$3 $1 mutat în ~/.Downloads/$1!”
    fi
}

# elimina directoarele goale
pentru emptyDir în `find ~/Desktop/ ~/Downloads/ -empty -type d`; do
    notify-send "Directoul $emptyDir a fost șters, deoarece era gol!"
Terminat
găsiți ~/Desktop/ ~/Downloads/ -empty -type d -delete

# eliminați / mutați fișierele / directorul vechi
dacă [ -z „$1” ] || [ "${1,,}" != "șterge" ] && [ "${1,,}" != "mută" ]; atunci
    echo „Dă ca mod parametru (șterge/mută)”
    Ieșire
fi

if [ "${1,,}" == "șterge" ]; atunci
    zi=30
    path=".Descărcări"
    mode="DELETE"
altfel
    zi=2
    path="Descărcări"
    mode="MOVE"
  cr  
  dacă [ ! -d "~/.Descărcări" ]; atunci
    mkdir -p ~/.Descărcări
  fi
fi

cd ~/$cale

pentru element în *
do
    if [ -d "$element" ]; atunci
        if [ $(găsește „$element” -tip f -mtime -$zi | wc -l) -eq 0 ]; atunci
            procesează „$element” „$mode” „Director”
        fi
    altfel
        if [ $(găsește `pwd` -nume "$element" -mtime +$zi | wc -l) -gt 0 ]; atunci
            procesează „$element” „$mode” „Fișier”
        fi
    fi
Terminat

V-aș ruga cu drag să-mi spuneți ce aș putea face greșit.

Mulțumesc anticipat!

GammaGames avatar
drapel in
Ai putea pune ceva la fel de simplu ca `@reboot [nume utilizator] find ~/Downloads/ -mtime +3 -exec gio trash {} \;` în crontab. Distribuția mea este setată să ștergă fișierele gunoi după 30 de zile, dar asta se poate face și manual cu pachetul „trash-cli”.
Puncte:13
drapel hr

tl;dr: nu sunt spațiile, ci parantezele1

The găsi ale comenzii -Nume testul folosește expresii shell glob - adăugarea de ghilimele în jurul argumentului împiedică interpretarea caracterelor speciale glob de către dvs. coajă, dar găsi mai cere ca ei să fie evadat.

Ex.

$ atingeți „numele fișierului cu [paranteze] în el”
$ găsiți. -name „nume fișier cu [paranteze] în el”
$

(fără rezultate - pentru că [paranteze] înseamnă orice caracter unic din set b, r, A, c, k, e, t, s); întrucât

$ găsiți. -name „nume fișier cu \[paranteze\] în el”
./nume fișier cu [paranteze] în el

Dacă trebuie să implementați acest lucru în mod programatic, ați putea utiliza shell-ul bash printf pentru a adăuga evadările necesare:

$ element='nume fișier cu [paranteze] în el'
$ găsiți. -nume "$(printf '%q' "$element")"
./nume fișier cu [paranteze] în el

  1. cu toate acestea, veți avea o problemă cu spațiul alb în linie

    pentru emptyDir în `find ~/Desktop/ ~/Downloads/ -empty -type d`; do
    

    Vedea De ce este o practică proastă să faceți loop peste ieșirea find?

  2. există o serie de alte probleme, de exemplu cele citate ~ în [ ! -d „~/.Descărcări”] nu se va extinde la $HOME - în general ar trebui să evitați ~ în scenarii

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.