Rimuovere tutte le cartelle che non contengono un nome specifico in UNIX


1

Sto cercando di capire la mia vecchia abilità in * nix.

Quello che sto cercando di ottenere è rimuovere ogni cartella che non contiene una parola specifica.

Questa è la lista

  myfolder: pwd
/user/myfolder

  myfolder: ll locale

drwxr-xr-x  3 user  staff  102 23 Oct 11:13 bn_BD
drwxr-xr-x  3 user  staff  102 23 Oct 11:13 bn_IN
drwxr-xr-x  3 user  staff  102 22 Oct 19:03 en_CA
drwxr-xr-x  8 user  staff  272  9 Dec 16:10 en_US
drwxr-xr-x  3 user  staff  102 22 Oct 19:03 es
drwxr-xr-x  3 user  staff  102 21 Oct 13:18 fr
drwxr-xr-x  3 user  staff  102 23 Oct 11:13 pt
drwxr-xr-x  3 user  staff  102 21 Oct 13:18 ru
drwxr-xr-x  3 user  staff  102 21 Oct 13:18 th_TH

Ora voglio rimuovere tutto tranne en_US

Non so cosa sia il non nel comando

rm -rf locale/[!somethinghere]

Risposte:


3

Con GNU find (e forse anche altre versioni), puoi usare un punto esclamativo per invertire una ricerca - così questo troverà ed eliminerà tutto nella directory corrente tranne 'en_us':

find . ! -name 'en_US' -delete
##  If you only want to delete directories:
find . -type d ! -name 'en_US' -delete
##  If you *don't* want recursiveness:
find . -maxdepth 1 -type d ! -name 'en_US' -delete
##  If you want to avoid deleting dotfiles:
find . -maxdepth 1 -type d ! -name 'en_US' -a ! '.*' -delete

Alcune versioni di findnon hanno l' -deleteopzione; invece potresti usare uno di:

find . -maxdepth 1 -type d ! -name 'en_US' -exec rm -r '{}' +
find . -maxdepth 1 -type d ! -name 'en_US' -a ! '.*' -exec rm -r '{}' +

In alternativa, poiché hai menzionato in un commento che hai zsh,

setopt extendedglob  ##  this may already be set in you .zshrc
rm ^*en_US*
##  If you only want to delete directories:
rm ^*en_US*(/)

Tuo molto simile a quello che ho trovato tranne che non riesco a usare -delete?
Ali,

Cosa find --versionti dà? Stai usando GNU find o qualcos'altro?
evilsoup,

Lo uso solo finddal mio Mac OS X?
Ali,

1
Ahh. Avresti dovuto specificare OSX nei tuoi tag (stavo assumendo erroneamente Linux). Usa le versioni BSD dei vari strumenti da riga di comando, mentre io sono abituato alle versioni GNU che usano la maggior parte di Linux. Forse prova la nuova versione del comando nell'ultima versione della mia risposta.
evilsoup,

Mi dispiace per quel @evilsoup .. Avrei dovuto menzionarlo>. <
Ali

1

Una soluzione a tre righe funzionerà (testata con Linux bash):

tar cvf foo $(find locale -name en_US)
rm -fr locale
tar xvf foo

Questo è:

  • Salva ciò che vuoi conservare
  • Elimina originale
  • Ripristina ciò che hai salvato

Ho giocato con qualcosa del genere find locale \( -name en_US -true \) -o -print | xargs ..., ma questo sembra più complicato. E più rischioso, se le abilità di Unix sono arrugginite.


Preferirei la seconda opzione solo se riesco a capire perché continui a corrispondere anche a "en_US"
Ali

0

Questo è quello che finisco per fare.

find locale -type d ! -name 'en_US' ! -name 'locale' | xargs rm -rf

Il motivo per cui devo includere anche "locale" perché xargsrestituitolocale locale/bn_BD locale/bn_IN locale/en_CA locale/es locale/fr locale/pt locale/ru locale/th_TH

Ora li ho cancellati

#   deleted:    locale/bn_BD/goggles.webmaker.org.json
#   deleted:    locale/bn_IN/goggles.webmaker.org.json
#   deleted:    locale/en_CA/goggles.webmaker.org.json
#   deleted:    locale/es/goggles.webmaker.org.json
#   deleted:    locale/fr/goggles.webmaker.org.json
#   deleted:    locale/pt/goggles.webmaker.org.json
#   deleted:    locale/ru/goggles.webmaker.org.json
#   deleted:    locale/th_TH/goggles.webmaker.org.json

1
Non si dovrebbe pipe findoutput xargs, a meno che non si utilizza find … -print0 | xargs -0 ….
Slhck,

0

Puoi farlo usando l'espansione bash: rm -rf path/to/!(something.*)

Modificare:

Come menzionato nei commenti seguenti, questo comando funziona se è abilitato il formato globbing esteso .

Puoi abilitarlo con il comando shopt -s extglobin bash o setopt kshglobin zsh .


1
Non so se sia per via di questo, zshma sto ottenendo questozsh: no matches found: locale/!(en_US.*)/
Ali

È necessario utilizzare shopt -s extglobper abilitare questo comportamento in bash; la sintassi per zsh è diversa.
evilsoup,

@evilsoup Non sono sicuro di cosa significhi? shopt -s extglob?
Ali,

Se si utilizza bash, è necessario immettere il comando shopt -s extglobper abilitare il globbing esteso, che consente di utilizzare la !(pattern*)sintassi in questa risposta. Ma stai usando zsh, che usa un diverso tipo di glob esteso. Io penso che se si immette il comando setopt kshglob, si dovrebbe essere in grado di utilizzare questa risposta.
evilsoup,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.