Come eliminare selettivamente file con Bash

Cerca

A volte si ha la necessità di dover cancellare tutti i file contenuti contenuti in una directory eccetto uno o più file con un certo nome o con una particolare estensione.

In questo articolo trattiamo 3 modi per cancellare tutti i file presenti in una cartella escludendo quelli di un certo tipo e per farlo utilizziamo i comandi rm, find e globignore.

Tabella dei Contenuti

Filename pattern matching

Prima di addentrarci nell’uso dei comandi, diamo uno sguardo ad un concetto fondamentale in Linux, ossia il filename pattern matching, che ci permette di affrontare agevolmente il problema in questione.

In Linux esistono i cosidetti shell pattern, delle stringhe composte dai seguenti caratteri speciali denominati anche wildcards o metacharacters:

  • * – zero o più caratteri
  • ? – un singolo carattere
  • [seq] – qualsiasi carattere che compone seq
  • [!seq] – qualsiasi carattere non incluso in seq

 

Cancellare file usando gli Extended Pattern Matching Operators

Questi operatori estesi permettono di eseguire un pattern matching articolato. Facendo seguire i caratteri wildcards da una pattern-list, ossia una lista contenente uno o più filename separati usando il carattere |.

  • *(pattern-list) – zero o più occorrenze di uno specifico pattern
  • ?(pattern-list) – zero o una occorrenza di uno specifico pattern
  • +(pattern-list) – una o più occorrenze di uno specifico pattern
  • @(pattern-list) - uno tra i pattern specificati
  • !(pattern-list) - qualsiasi cosa tranne il pattern specificato

Per poter utilizzare questi operatori avanzati dobbiamo preventivamente attivare l’opzione di shell extglob:

				
					shopt -s extglob
				
			
Cancellare tutti i file tranne uno specifico

Il seguente comando permette di cancellare tutti i file della directory tranne quello specificato tra parentesi.

				
					rm -v !("filename")
				
			
Cancellare tutti i file tranne una lista di specifici

Utilizzando l’operatore | possiamo concatenare tutti i nomi dei file che vogliamo preservare dalla cancellazione.

				
					rm -v !("filename1"|"filename2"|"...")
				
			
Cancellare tutti i file tranne quelli con una certa estensione

In questo esempio cancelliamo tutti i file diversi dagli archivi .zip

				
					rm -i !(*.zip)
				
			

Estendendo il concetto visto prima, possiamo utilizzare l’operatore | per escludere dalla cancellazione sia gli archivi .zip che i file .odt

				
					rm -i !(*.zip|*.odt)
				
			
Disabilitare gli operatori avanzati di pattern matching

Una volta che abbiamo terminato di utilizzare gli operatori avanzati disabilitiamoli con questo comando:

				
					shopt -u extglob
				
			

Cancellare file con il comando find

Utilizzando il comando find di Linux con le appropriate opzioni o in combinazione con il comando xargs possiamo ottenere degli ottimi risultati.

				
					find /directory/ -type f -not -name 'PATTERN' -delete
find /directory/ -type f -not -name 'PATTERN' -print0 | xargs -0 -I {} rm {}
find /directory/ -type f -not -name 'PATTERN' -print0 | xargs -0 -I {} rm [options] {}
				
			
Cancellare tutti i file tranne quelli con una certa estensione

Riprendendo l’esempio di prima, cancelliamo tutti i file diversi che non sono archivi .zip

				
					find . -type f -not -name '*.zip'-delete
				
			

Allo stesso modo possiamo utilizzare find in combinazione con xargs

				
					find . -type f -not -name '*.zip' -print0 | xargs -0  -I {} rm -v {}
				
			
Cancellare tutti i file tranne una serie con una certa estensione
				
					find . -type f -not \(-name '*.zip' -or -name '*.odt' -or -name '*.jpg' \) -delete
				
			

Cancellare file sfruttando la variabile Bash GLOBIGNORE

L’ultimo approccio al problema che vediamo in questo articolo sfrutta la variabile Bash GLOBIGNORE, la quale memorizza una pattern-list (filenames) separata dal carattere dei due punti.

Come prima cosa istanziamo la variabile indicando i nomi dei file che vogliamo escludere. In questo esempio escludiamo i file con le seguenti estensioni:

				
					GLOBIGNORE=*.odt:*.iso:*.txt
				
			

A questo punto possiamo eseguire in sicurezza il comando per eliminare tutti i file presenti in cartella:

				
					rm -v *
				
			

Una volta che abbiamo terminato il task, ricordiamoci di ripristinare la normalità spegnendo la variabile GLOBEIGNORE:

				
					unset GLOBIGNORE
				
			

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Most Recent

Come aggiornare mailcow

In questo scenario viene illustrato come eseguire l’aggiornamento di un’istanza di mailcow dockerized utilizzando i tools in esso integrati. Aggiornamento automatico Nella directory di mailcow-dockerized

Partners