Come analizzare correttamente i nomi dei file in Bash

Contenuti

Bash Shell

Le convenzioni di denominazione dei file Bash sono molto ricche ed è facile creare uno script o una riga che analizzi erroneamente i nomi dei file. Impara ad analizzare correttamente i nomi dei file e, perché, assicurati che i tuoi script funzionino come previsto.

Il problema di analizzare correttamente i nomi dei file in Bash

Se usi Bash da un po' e scrivi nel suo ricco linguaggio Bash, probabilmente hai riscontrato alcuni problemi di analisi del nome del file. Diamo un'occhiata a un semplice esempio di cosa può andare storto:

tocca 'a
> B'

Imposta un file con un carattere CR nel nome del file

Qui creiamo un file che ha un CR (restituzione dell'auto) inserito premendo invio dopo il a. Le convenzioni di denominazione dei file Bash sono molto ricche, e anche se in qualche modo è figo, possiamo usare caratteri speciali come questi in un nome di file, vediamo come si comporta questo file quando proviamo a eseguire alcune azioni su di esso:

ls | xargs rm

Il problema nel tentativo di gestire un nome file che include CR

Questo non è funzionale. xargs prenderà l'input di ls (attraverso di lui | tubatura) e passalo a rm, Ma qualcosa è andato storto nella procedura!

Quello che è andato storto è che l'output di ls è preso alla lettera da xargs, e l'"entra"’ (CR – restituzione dell'auto) all'interno del nome del file è visto da xargs come un vero personaggio finale, non un CR essere passato a rm come dovrebbe essere.

Esemplifichiamo questo in un altro modo:

ls | xargs -I{} eco '{}|'

Mostrare come xargs vedrà il carattere CR come una nuova riga e dividerà i dati su di esso

È chiaro: xargs Si sta elaborando l'input come due singole righe, dividere il nome del file originale in due. Anche se dovessimo risolvere i problemi di spazio attraverso un'analisi elegante usando la sete, presto avremmo incontrato altri problemi quando abbiamo iniziato a usare altri caratteri speciali come spazi., barre posteriori, virgolette e altro ancora.

touch 'a
b'
touch 'a b'
touch 'ab'
touch 'a"b'
touch "a'b"
ls

Tutti i tipi di caratteri speciali nei nomi dei file.

Anche se sei uno sviluppatore Bash esperto, Potresti essere scosso dalla visualizzazione di nomi di file come questo, poiché sarebbe molto complesso, per gli strumenti Bash più comuni, Eseguire correttamente la scansione di questi file. Dovresti fare tutti i tipi di modifiche alla catena affinché questo funzioni.. In altre parole, a meno che tu non abbia la ricetta segreta.

Prima di immergerci in questo, c'è un'altra cosa, qualcosa che dovresti sapere, potresti incontrare durante l'analisi ls produzione. Se usi la codifica a colori per gli elenchi delle directory, che è abilitato di default in Ubuntu, è facile eseguire un altro set di ls problemi di analisi.

Questi non sono veramente correlati al modo in cui vengono nominati i file, ma piuttosto con come i file sono presentati come output da ls. il ls l'output conterrà codici esadecimali che rappresentano il colore da utilizzare nel terminale.

Per evitare di incontrarli, basta usare --color=never come opzione per ls:
ls --color=never.

e menta 20 (un ottimo sistema operativo derivato da Ubuntu), questo problema sembra risolto, anche se è possibile che il problema sia ancora presente in molte altre versioni di Ubuntu o precedenti, eccetera. Ho riscontrato questo problema a metà agosto 2020 in Ubuntu.

Anche se non usi la codifica a colori per gli elenchi delle tue directory, è probabile che il tuo script venga eseguito su altri sistemi che non sono di tua proprietà o gestiti da te. In quel caso, vorrai anche usare questa opzione per impedire agli utenti di quella macchina di incorrere nel problema descritto.

Tornando alla nostra ricetta segreta, Vediamo come possiamo assicurarci di non avere problemi con i caratteri speciali nei nomi dei file Bash. La risposta fornita evita ogni uso di ls, che faresti bene ad evitare in generale, quindi anche i problemi di codifica dei colori non sono applicabili.

Ci sono ancora momenti in cui ls L'analisi è veloce e conveniente, ma sarà sempre complicato e probabilmente "sporco"’ non appena vengono immessi caratteri speciali, per non parlare del fatto che non sono sicuri (i caratteri speciali possono essere usati per introdurre tutti i tipi di problemi).

La ricetta segreta: Terminazione NULL

Gli sviluppatori di strumenti Bash hanno realizzato questo stesso problema molti anni prima e ci hanno fornito: NULL terminazione!

Che cos'è NULL domande di completamento? Considera come negli esempi precedenti, CR (il letteralmente entrare dentro) era il protagonista finale.

Abbiamo anche visto come puoi usare caratteri speciali come le virgolette, spazi e barre rovesciate nei nomi dei file, anche se hanno funzioni speciali quando si tratta di altri strumenti di analisi e modifica del testo Bash come sed. Ora confronta questo con il -0 opzione a xargs, a partire dal man xargs:

-0, -nullo Gli elementi di input terminano con un carattere nullo anziché uno spazio vuoto, e le virgolette e la barra rovesciata non sono speciali (tutti i personaggi sono presi alla lettera). Disabilita la stringa di fine file, che viene trattato come qualsiasi altro argomento. Utile quando gli elementi di input possono contenere spazi vuoti, citazioni o barre rovesciate. L'opzione GNU find -print0 produce un input adatto per questa modalità.

E il -print0 opzione a find, a partire dal man find:

-fprint0 archivio Certo; stampa il nome completo del file sullo standard output, seguito da un carattere nullo (invece del carattere di nuova riga che usa -print). Ciò consente ai programmi che elaborano l'output della ricerca di interpretare correttamente i nomi di file che contengono nuove righe o altri tipi di spazi bianchi.. Questa opzione corrisponde all'opzione -0 de xargs.

il Certo; qui significa Se l'opzione è specificata, quanto segue è vero;. Interessanti anche i due chiari avvertimenti che vengono dati in altre parti della stessa pagina di manuale:

  • Se stai reindirizzando l'output di find a un altro programma e c'è la minima possibilità che i file che stai cercando contengano una nuova riga, allora dovresti seriamente considerare di usare l'opzione -print0 invece di -print. Vedere la sezione NOMI FILE INUSUALI per informazioni su come vengono gestiti i caratteri insoliti nei nomi di file..
  • Se stai usando la ricerca in uno script o in una situazione in cui i file corrispondenti possono avere nomi arbitrari, È consigliabile utilizzare -print0 anziché -print.

Questi chiari avvertimenti ci ricordano che l'analisi dei nomi dei file in bash può essere, E questo è, un business complicato. Nonostante questo, con le giuste alternative per find, vale a dire -print0, e xargs, vale a dire -0, Tutti i nostri caratteri speciali contenenti nomi di file possono essere scansionati correttamente:

ls
find . -name 'a*' -print0 
find . -nome 'a*' -print0 | xargs -0 ls
find . -nome 'a*' -print0 | xargs -0 rm

La soluzione: find -print0 e xargs -0

Per prima cosa esaminiamo il nostro elenco di directory. Tutti i nostri nomi di file contenenti caratteri speciali sono presenti. Successivamente facciamo un semplice find ... -print0 per vedere l'output. Osserviamo che le stringhe sono NULL finito (con il NULL oh – lo stesso personaggio – non visibile).

Notiamo anche che ce n'è solo uno CR all'uscita, che corrisponde al singolo CR che avevamo inserito nel nome del primo file, composto da un seguito da entrare dentro seguito da B.

Finire, l'output non introduce una nuova riga (che contiene anche CR) prima di restituire il $ indicatore del terminale, poiché le catene erano NULL e no CR finito. Premiamo invio nel $ prompt del terminale per spiegare un po' le cose.

Poi aggiungiamo xargs con il -0 opzioni, cosa abilita xargs per gestire il NULL finito la voce correttamente. Vediamo che l'input è passato e ricevuto da ls è chiaro e non c'è alterazione della trasformazione del testo.

Per finire riproviamo il nostro rm comando, e questa volta per tutti i file, compreso l'originale contenente il CR con chi abbiamo avuto problemi. il rm funziona alla grande e non ci sono errori o problemi di analisi. Eccellente!

Fine

Abbiamo visto quanto sia essenziale, in diversi casi, analizzare e gestire correttamente i nomi dei file in bash. Mentre impari ad usare find correttamente è un po' più impegnativo del semplice utilizzo ls, i benefici che offre possono ripagare alla fine. Maggiore sicurezza e senza problemi con i caratteri speciali.

Se ti è piaciuto questo post, potresti anche voler leggere Come rinominare i file in nomi di file numerici in Linux, mostrando un interessante e un po' complesso find -print0 | xargs -0 dichiarazione. Godere!

Iscriviti alla nostra Newsletter

Non ti invieremo posta SPAM. Lo odiamo quanto te.