Evitare di elencare i file che terminano con ~ (file di backup)


20

Il mio requisito è elencare tutti i file in una directory, ad eccezione dei file che terminano con un ~(file di backup).

Ho provato ad usare il comando:

ls -l | grep -v ~    

Ottengo questo risultato:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

Voglio ottenere solo questi file:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt

Sembra che tu stia cercando di evitare di elencare i file che terminano con a ~. Questi file sono file di backup creati con alcuni editor di testo.
ctrl-alt-delor,

Quale sistema operativo stai usando: è un Gnu / Linux (come Debian, Ubuntu, Redhat, Centos, Fedora, Suse, Mint, Arch, ...)?
ctrl-alt-delor,

2
Si noti che il file che si desidera ignorare sembra essere un file di backup di Emacs. È piuttosto facile cambiare il comportamento di Emacs in modo da salvare i backup in una directory centralizzata e non ovunque; vedi emacs.stackexchange.com/questions/33/…
Kilian Foth,

Mi dispiace essere cattivo ma non ti credo; ls -l(lettera ell) includerebbe i permessi, i collegamenti, il proprietario, la dimensione e il modtime per ogni file elencato. Ciò che produrrebbe l'output che mostri è ls -1(cifra uno) e su molti sistemi -1è necessario per produrre output a colonna singola sul terminale , ma quando lsviene convogliato (come qui grep) o reindirizzato, -1non è necessario, è già a colonna singola .
dave_thompson_085

@ dave_thompson_085 Ho troncato tutto il testo e solo i nomi dei file qui .. Perché ho sentito che è irrilevante. E anche questo è un sistema di produzione (non il mio sistema). Quindi non voglio elencare nomi utente, dettagli e perderli.
curious_one,

Risposte:


49
ls -l | grep -v ~

Il motivo per cui non funziona è che la tilde viene espansa nella directory home, quindi grepnon vede mai una tilde letterale. (Vedi ad esempio il manuale di Bash su Tilde Expansion .) Devi citarlo per evitare l'espansione, ad es

ls -l | grep -v "~"

Naturalmente, questo rimuoverà comunque qualsiasi linea di output con una tilde ovunque, anche nel mezzo di un nome di file o altrove lsnell'output (anche se probabilmente non è probabile che appaia in nomi utente, date o simili). Se vuoi davvero ignorare solo i file che terminano con una tilde, puoi usarli

ls -l | grep -v "~$"

48

L'implementazione GNU di ls(presente sulla maggior parte dei sistemi Linux) ha un'opzione per questo: -BIgnora i backup:

ls --ignore-backups

24

Se stai usando bash, assicurati che extglobsia abilitato:

shopt -s extglob

Quindi puoi usare:

ls -d -- !(*~)
  • -d per non mostrare i contenuti delle directory
  • !(*~) tutti i file tranne quelli che terminano con ~

Su zsh, puoi fare lo stesso con l' kshglobopzione o usando i suoi globs estesi:

setopt extended_glob
ls -d -- ^*~

Poiché il suffisso da escludere è lungo solo un carattere, potresti anche abbinare nomi di file in cui l'ultimo carattere non è la tilde (anche questo dovrebbe funzionare senza extglob):

ls -d -- *[^~]

Ma l'idea generale è di usare ls --ignore-backups.


12

Questo dovrebbe aiutare:

ls -l | grep -v '~'  

Motivo: ~ char viene sostituito dalla directory home prima dell'esecuzione del comando. Provare

echo ~

e

echo '~'

6

Come menzionato in altre risposte, il motivo per cui probabilmente hai problemi è perché non hai citato o sfuggito alla tilde.

Per un caso d'uso particolare ho usato l'espansione del nome file della shell per fare qualcosa di simile. Lo uso da circa il 2003, il che significa che ha funzionato su una vasta gamma di implementazioni shell su diversi tipi di sistemi. (qui lo uso anche -Cperché voglio una bella visualizzazione in colonne ordinate)

ls -C *[!~]

(una limitazione con l'utilizzo dell'espansione del nome file della shell è ovviamente che una directory con un numero molto elevato di file (non di backup) farà sì che l'espansione superi la dimensione dell'elenco degli argomenti disponibili, sebbene nella maggior parte dei sistemi moderni questo limite sia piuttosto elevato, spesso 250 KB o più, a volte molto di più)


1

ls | grep -v '~$'è la soluzione rapida. Usa ls per elencare tutti i file (non nascosti), quindi usa grep con -v(corrispondenza inversa, cioè esclusione) per escludere tutte le righe con tilde ( ~) alla fine ( $).

TUTTAVIA, se hai QUALSIASI file chiamato come qualcosa1, qualcosa2, è un GRANDE indicatore puzzolente che hai un cattivo flusso di lavoro, che dovresti correggere alla fonte, non con hack ingombranti come modificare il modo in cui funziona.

Se ti trovi a nominare i file con i numeri di versione, come test1 e test2 o testone e testtwo, allora quello che vuoi davvero è un sistema di controllo della versione, come git.

Ciò è particolarmente vero nel tuo caso, in cui hai più versioni di più file e sembra che il controllo delle versioni debba essere coordinato tra tutti i file.

I sistemi di controllo della versione ti consentono essenzialmente di sovrapporre una finestra temporale sul filesystem, quindi puoi vedere solo un testfile, ma sotto il cofano (attraverso il programma di controllo della versione) sono disponibili tutte le versioni per cercare, recuperare, ripristinare, confrontare con, ecc. .

Una volta che hai impostato questo, non hai più bisogno di file di backup dal tuo editor, perché il controllo di versione ha la cronologia dei file da quando hai iniziato a usarlo, anche se da allora hai apportato mille modifiche. Puoi persino "ramificare" la cronologia della cronologia, provare una nuova idea e tornare indietro nel tempo e poi in avanti per provare un'idea diversa, se necessario.


1

Sebbene molte risposte siano corrette (mi piace @Foonquella in particolare), noterei che ottenere l'elenco dei nomi ls -lè un po 'zoppo per vari motivi.

Lo strumento giusto per trovare i file è, ovviamente, find.

Uno dei suoi upshots è che è in grado di gestire da solo la "logica di selezione", ad esempio:

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

che dice letteralmente finda:

  1. Cerca i file nella directory corrente: .
  2. Cercali solo a livello di quella directory, ovvero non ricorrere: -maxdepth 1
  3. Lì, cerca entità, che

    • di tipo file: -type f
    • e: -a
    • i cui nomi non finiscono in ~: ! -name *~ (dove !nega la seguente direttiva che corrisponde ai nomi dei file, -name *~).

    (Per far apparire l'intera corrispondenza per tipo e nome come un'unità logica, è tra parentesi con (e )).

  4. Stampa il nome di ogni file trovato: -print.

È necessario proteggere alcuni caratteri che sono speciali per la shell dall'essere interpretati dalla shell, ed è per questo che le parentesi e il botto !, sono sottoposti a backslash e il modello del nome *~, è racchiuso tra virgolette singole.

Il findcomando possiede un mini-linguaggio molto potente attraverso l'uso delle sue opzioni. Ad esempio, è possibile che venga detto di elaborare in modo ricorsivo un intero albero di file system (o alberi) ma di omettere determinate directory durante la scansione. È possibile abbinare diversi attributi dei file, come il tempo di creazione o modifica o le dimensioni di qualunque cosa.

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.