GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso analizzare l'output del comando find quando i nomi dei file contengono spazi?

Idealmente non lo fai affatto in questo modo, perché analizzare correttamente i nomi dei file in uno script di shell è sempre difficile (correggilo per gli spazi, avrai ancora problemi con altri caratteri incorporati, in particolare la nuova riga). Questo è anche elencato come la prima voce nella pagina BashPitfalls.

Detto questo, c'è un modo per fare quasi quello che vuoi:

oIFS=$IFS
IFS=$'\n'

find . -name '*.txt' | while read -r i; do
  # use "$i" with whatever you're doing
done

IFS=$oIFS

Ricordati di citare anche $i quando lo si utilizza, per evitare altre cose interpretando gli spazi in seguito. Ricorda inoltre di impostare $IFS indietro dopo averlo usato, perché non farlo causerà errori sconcertanti in seguito.

Questo ha un altro avvertimento:cosa succede all'interno del while loop può avvenire in una subshell, a seconda della shell esatta che stai utilizzando, quindi le impostazioni delle variabili potrebbero non persistere. Il for la versione loop lo evita ma al prezzo che, anche se applichi il $IFS soluzione per evitare problemi con gli spazi, ti ritroverai nei guai se find restituisce troppi file.

Ad un certo punto la soluzione corretta per tutto questo diventa farlo in un linguaggio come Perl o Python invece che in shell.


Usa find -print0 e reindirizzalo a xargs -0 , o scrivi il tuo piccolo programma C e invialo al tuo piccolo programma C. Questo è ciò che -print0 e -0 sono stati inventati per.

Gli script di shell non sono il modo migliore per gestire i nomi di file con spazi all'interno:puoi farlo, ma diventa goffo.


Puoi impostare il "separatore di campo interno" (IFS ) in qualcosa di diverso dallo spazio per la suddivisione degli argomenti del ciclo, ad esempio

ORIGIFS=${IFS}
NL='
'
IFS=${NL}
for i in $(find . -name '*.txt'); do
    IFS=${ORIGIFS}
    #do stuff
done
IFS=${ORIGIFS}

Ho resettato IFS dopo il suo utilizzo in find, soprattutto perché ha un bell'aspetto, credo. Non ho riscontrato alcun problema nell'averlo impostato su newline, ma penso che questo sia "più pulito".

Un altro metodo, a seconda di cosa vuoi fare con l'output di find , consiste nell'usare direttamente -exec con il find comando o usa -print0 e reindirizzalo in xargs -0 . Nel primo caso find si occupa dell'escape del nome del file. Nel -print0 caso, find stampa il suo output con un separatore null, quindi xargs si divide su questo. Poiché nessun nome di file può contenere quel carattere (quello che so), anche questo è sempre sicuro. Questo è utile soprattutto in casi semplici; e di solito non è un ottimo sostituto per un for completo ciclo.


Linux
  1. Come dire a quale versione di Os X mi trovo dalla riga di comando?

  2. Qual è la differenza tra individuare e trovare il comando in Linux

  3. Come si specificano i nomi dei file all'interno di uno zip durante la creazione sulla riga di comando da una pipe?

  4. Come aggiungere l'output a un file?

  5. Cosa significa il simbolo della pipe Linux | fare?

Come trovare file in Linux con il comando Trova

Come modificare il colore di output di "Echo" in Linux

Come trovare file con il comando fd in Linux

Come trovare l'utilizzo della CPU, cosa blocca il sistema

Come reindirizzare l'output di un comando a un file quando il comando richiederà gli input dell'utente?

Qual è la sintassi corretta di find -exec