Rimuovi tutti i file tranne N dalla directory in modo ricorsivo


4

Vorrei ridurre un grande database dalla riga di comando a N file, molto simile a Questo la domanda fa. L'unica differenza è che la maggior parte dei miei file sono in sottodirectory, quindi mi chiedevo se c'era una soluzione rapida al mio problema o se avrebbe richiesto un'azione più approfondita. Attualmente, il mio comando sembra (con il (N+1) sostituito con il numero appropriato):

find . -type f | sort -R | tail -n +(N+1) | xargs rm

Originariamente pensavo che avrebbe funzionato perché la ricerca per natura è ricorsiva, e quindi ho provato ad aggiungere il -r (bandiera ricorsiva) intorno al rm poiché l'output indica che seleziona casualmente i file ma non li trova da eliminare. Qualche idea?

MODIFICARE: Il mio nuovo comando ha questo aspetto:

find . -type f -print0 | sort -R | tail -n +(N+1) | xargs -0 rm

e ora ho l'errore che dice rm: missing operand. Inoltre, sono su una macchina CentOS quindi -z la bandiera non è disponibile per me.

MODIFICA # 2 Questo comando esegue:

find . -type f -print0 | sort -R | tail -n +(N+1) | xargs -0 -r rm

ma quando eseguo a find . -type f | wc -l per ottenere il numero di file nella directory (che dovrebbe essere N se il comando ha funzionato correttamente) non è cambiato dalla quantità iniziale di file.


Nota al n. 2: né semplice sort né semplice tail funziona con stringhe con terminazione nulla come vuoi tu.
Kamil Maciorowski

Questo è il motivo per cui vorrei poter usare il comando -z in quanto è ciò che internet dice di fare. Sfortunatamente CentOS non ha questa bandiera. Sai se c'è un modo per aggirare questo?
Alerra

Se hai davvero bisogno -print0, dovresti dichiararlo chiaramente perché (secondo me) questa è l'unica cosa che rende la tua domanda non un duplicato di quella collegata. Quindi dovresti anche menzionare esplicitamente l'incapacità di usare -z (con sort? tail? tutti e due?).
Kamil Maciorowski

@ KamilMaciorowski Non sono davvero sicuro se per qualche bisogno -print0ma molte delle soluzioni correlate che ho visto l'hanno usato. Nella domanda che ho originariamente collegato, ho visto le soluzioni con e senza di esso e quindi l'ho provato in entrambi i modi.
Alerra

In che modo il tuo comando originale fallisce? Qualche messaggio di errore?
Kamil Maciorowski

Risposte:


1

Se hai bisogno di usare find … -print0 e non puoi usare -z con sort e / o tail, c'è una soluzione possibile, ma ingombrante (sostituto (N+1) come di solito):

find . -type f -printf "%i\n" | sort | uniq | sort -R | tail -n +(N+1) |
   while read i; do
      find . -type f -inum "$i" -delete
   done

Il trucco sporco è che usiamo numeri di inode invece di percorsi.

L'interno find rimuove tutti i file con il numero di inode indicato sotto la directory corrente, quindi se alcuni file sono collegati l'uno all'altro si perderanno tutti o si terranno tutti.

Preliminare sort | uniq è quello di evitare una disavventura quando si perde troppo a causa di numeri di inode duplicati a causa di collegamenti fisici. Potresti finire con più di N nomi di file, indicando fino a N inode distinti in totale.

Nel caso in cui il tuo find non capisce -delete, uso -exec rm {} +.


Ho appena provato questo (ho dovuto modificare leggermente per eseguire direttamente dalla riga di comando e non come uno script), e ha funzionato perfettamente. Grazie!
Alerra

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.