Rimuovi tutti i tipi di file tranne uno (o più)


20

Ho cercato di trovare un comando per rimuovere tutti i file in una cartella ma non un tipo di tipo di file. Ma mi sembra di non avere fortuna. Quello che ho provato finora:

set extended_glob
rm !(*.dmg)
# this returns zsh:number expected

rm ./^*.dmg
# this returns no matches found 

La versione di zsh che sto usando è zsh 5.0.2 (x86_64-apple-darwin13.0.1).

Risposte:


22

L' extended_globopzione ti dà la sintassi globale estesa di zsh .

setopt extended_glob
rm -- ^*.dmg
rm -- ^*.(dmg|txt)

È possibile impostare l' ksh_globopzione per ottenere globs ksh . Fai attenzione che nel caso comune in cui il modello negativo è l'ultima cosa della parola, zsh può analizzare le parentesi come qualificazioni glob (non lo fa in modalità di emulazione ksh).

setopt ksh_glob
rm -- !(*.dmg|*.txt)
setopt no_bare_glob_qual
rm -- !(*.dmg)

Questo non sembra funzionare. Quando corro rm -r secrets/!(directory)continua a chiedere number expectedo talvolta mi dàevent not found: directory
CMCDragonkai

@CMCDragonkai "numero previsto" indica che non hai impostato l' ksh_globopzione. "Evento non trovato: directory" indica che stai eseguendo bash (che comprende anche la !(…)sintassi, ma solo dopo shopt -s extglob).
Gilles 'SO- smetti di essere malvagio' il

Come potrei correre bash quando ero nella mia shell zsh?
CMCDragonkai,

Per me, setopt ksh_glob; echo !(a|b)funziona mentre setopt ksh_glob; echo !(a)no ("numero previsto") ...
ThiefMaster,

@ThiefMaster Ho avuto lo stesso problema. è un insetto?
CodeTower,

5

Puoi usare al findposto della tua shell:

find . -mindepth 1 -maxdepth 1 ! -name "*.dmg" -delete

Da man find:

   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the shell.
   -name pattern
          Base of file name (the path with the leading directories removed)
          matches shell pattern pattern. 
   -delete
          Delete  files; true if removal succeeded.  If the removal failed,
          an error message is issued.  If -delete fails, find's exit status
          will be nonzero (when  it eventually exits).  Use of -delete 
          automatically turns on the -depth option.

Se non puoi utilizzarlo findper qualsiasi motivo, ecco un modo per farlo con zsh(o altre shell). zshessendo zsh, c'è probabilmente un modo più semplice di farlo, ma dato che sono un bashragazzo, questo è quello che mi è venuto in mente:

for file in *; do if [[ ! "$file" == *.dmg ]]; then rm $file; fi; done

sfortunatamente, ogni volta che uso find nel mio mac, esce dalla sessione zsh corrente senza preavviso. Hai lo stesso problema ? find [Process completed]
Dzung Nguyen,

1
@nXqd vedi la risposta aggiornata per un modo per farlo senza find. Ti suggerisco di pubblicare una domanda sul tuo findproblema, che non dovrebbe accadere. In tal caso, includere l'output di type -a find.
terdon

1
Anche in bash, c'è una soluzione più semplice:, rm !(*.dmg)dopo shopt -s extglob.
Gilles 'SO- smetti di essere malvagio' il

@terdon grazie per i tuoi suggerimenti di debug in shell. la sua produzione sembra corretta:find is a shell function find is /usr/bin/find
Dzung Nguyen,

@nXqd che non è corretto, non dovrebbe essere una funzione di shell, dovrebbe essere solo /usr/bin/find. Hai una funzione chiamata finddefinita in uno dei tuoi file di configurazione di bash. Dato che sei su OSX, questo è probabilmente ~/.profile.
terdon

3

Un altro modo per rimuovere i file è con find, xargse rm:

find . -mindepth 1 -maxdepth 1 ! -name '*.dmg' -print0 | xargs -0 rm
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.