E 'abbastanza facile da leggere il contenuto di una riga file di testo di Linux per riga in un guscio di script finchè avete a che fare con alcuni trucchi sottili. Ecco come farlo nel modo sicuro.
File, di testo, e modi di dire
Ogni linguaggio di programmazione ha una serie di idiomi. Questi sono lo standard, senza fronzoli modi per realizzare una serie di attività comuni. Sono il modo elementare o di default per usare una delle caratteristiche del linguaggio del programmatore sta lavorando con. Diventano parte di toolkit di un programmatore di schemi mentali.
Azioni come la lettura dei dati da file, lavorare con loop, e scambiando i valori di due variabili sono buoni esempi. Il programmatore saprà almeno un modo per raggiungere i propri scopi in maniera generica o vaniglia. Forse questo sarà sufficiente per il fabbisogno a portata di mano. O forse faranno abbelliscono il codice per renderlo più efficace o applicabile alla soluzione specifica che stanno sviluppando. Ma avere l'idioma building-block a portata di mano è un ottimo punto di partenza.
Conoscere e capire idiomi in una lingua rende più facile per prendere un nuovo linguaggio di programmazione, anche. Sapendo come le cose sono costruiti in una lingua e alla ricerca per l'equivalente, o il più vicino cosa in un'altra lingua è un buon modo di apprezzare le somiglianze e le differenze tra i linguaggi di programmazione che già conosci e fai parte stai imparando.
Lettura righe da un file: l'One-Liner
In Bash, è possibile utilizzare un
mentre
ciclo sulla riga di comando per leggere ogni riga di testo da un file e fare qualcosa con esso. Il nostro file di testo si chiama “data.txt.” Esso contiene una lista dei mesi dell'anno.
Gennaio febbraio marzo . . ottobre novembre Dicembre
Con il nostro semplice one-liner è:
mentre la linea di lettura; fare $ line echo; done & lt; data.txt
Il
mentre
ciclo legge una riga dal file, e il flusso di esecuzione del piccolo programma passa al corpo del ciclo. Il
eco
comando scrive la riga di testo nella finestra del terminale. Il tentativo di lettura fallisce quando non ci sono più righe da leggere, e il ciclo è fatto.
Un trucchetto è la capacità per reindirizzare un file in un ciclo . In altri linguaggi di programmazione, avresti bisogno di aprire il file, leggere da esso, e vicino di nuovo quando si aveva finito. Con Bash, si può semplicemente utilizzare il reindirizzamento di file e lasciare che il manico shell tutta quella roba di basso livello per voi.
Naturalmente, questo one-liner non è molto utile. Linux fornisce già la
gatto
comando, che fa esattamente questo per noi. Abbiamo creato un modo prolisso per sostituire un comando di tre lettere. Ma lo fa visibilmente dimostrare i principi di leggere da un file.
Che funziona abbastanza bene, fino a un certo punto. Supponiamo di avere un altro file di testo che contiene i nomi dei mesi. In questo file, la sequenza di escape per un carattere nuova riga è stato aggiunto ad ogni linea. Che chiameremo “data2.txt.”
Gennaio \ n Febbraio \ n Marzo \ n . . Ottobre \ n Novembre \ n Dicembre \ n
Usiamo la nostra one-liner sul nostro nuovo file.
mentre la linea di lettura; fare $ line echo; done & lt; data2.txt
Il carattere barra rovesciata”
\
”È stato scartato. Il risultato è che un “n” è stato aggiunto a ciascuna linea. Bash interpreta il backslash come l'inizio di un
sequenza di escape
. Spesso, non vogliamo Bash di interpretare ciò che sta leggendo. Può essere più conveniente per leggere una riga nelle sue sequenze di escape interezza-backslash e tutto e scegliere ciò che per analizzare fuori o sostituire da soli, entro il proprio codice.
Se vogliamo fare qualsiasi elaborazione significativo o analisi sulle righe di testo, avremo bisogno di utilizzare uno script.
Lettura linee di un file con uno script
Ecco il nostro script. Si chiama “script1.sh.”
#! / Bin / bash
Contatore = 0
mentre IFS = '' read -r LinefromFile [116 ] || [[ -n " $ {} LinefromFile " ] ]; fare
(( Contatore ++ ))
eco "Accesso linea $ Contatore : $ {LinefromFile} " [9 ]
fatto & lt; " $ 1 "
Abbiamo impostato una variabile chiamata
Contatore
a zero, quindi definiamo il nostro
mentre
ciclo continuo.
La prima affermazione sulla linea mentre è
Ifs = ''
.
IFS.
Sta per il separatore interno del campo. Tiene valori che Bash utilizza per identificare i confini della parola. Per impostazione predefinita, il comando di lettura si spinge a spronizzare lo spazio bianco principale e finale. Se vogliamo leggere le righe dal file esattamente come lo sono, dobbiamo impostare
IFS.
essere una stringa vuota.
Potremmo impostare questo una volta al di fuori del loop, proprio come stiamo impostando il valore di
Contatore
. Ma con script più complessi, specialmente quelli con molte funzioni definite dall'utente in esse, è possibile che
IFS.
potrebbe essere impostato su valori diversi altrove nello script. Garantire che.
IFS.
è impostato su una stringa vuota ogni volta il tempo
mentre
Loop Iterates garantisce che sappiamo qual è il suo comportamento.
Leggeremo una linea di testo in una variabile chiamata
Linfromfile.
. Stiamo usando
-R
(Leggi il backslash come carattere normale) opzione per ignorare le backslash. Saranno trattati proprio come qualsiasi altro carattere e non riceverai alcun trattamento speciale.
Ci sono due condizioni che soddisferanno il
mentre
Loop e consentire al testo di essere elaborato dal corpo del loop:
-
Leggi -R Linefromfile.: Quando una riga di testo viene letto correttamente dal file, illeggereComando invia un segnale di successo almentre, e ilmentreLoop passa il flusso di esecuzione sul corpo del loop. Si noti che The..leggereil comando deve vedere a personaggio di Newline. Alla fine della linea di testo per considerarlo una lettura riuscita. Se il file non è un Posix file di testo conforme, il L'ultima riga potrebbe non includere un carattere newline . Se laleggereil comando vede il fine del marker di file (EOF) Prima della linea è terminata da una nuova linea, lo farà non trattalo come letto di successo. Se ciò accade, l'ultima riga del testo non verrà passata al corpo del loop e non verrà elaborata. -
[-n "$ {linefromfile}"]: Abbiamo bisogno di fare un lavoro extra per gestire i file compatibili non posizionati. Questo confronto controlla il testo che viene letto dal file. Se non è terminato con un carattere di newline, questo confronto restituirà ancora il successo verso ilmentreciclo continuo. Ciò garantisce che eventuali frammenti della linea finale siano trattati dal corpo del loop.
Queste due clausole sono separate dall'operatore o logico "
||.
"Così se
o
La clausola restituisce il successo, il testo recuperato viene elaborato dal corpo del ciclo, indipendentemente dal fatto che vi sia un carattere newline o meno.
Nel corpo del nostro loop, stiamo incrementando il
Contatore
variabile da uno e usando
eco
Per inviare un po 'di output alla finestra del terminale. Vengono visualizzati il numero di linea e il testo di ciascuna riga.
Possiamo ancora usare il nostro trucco di reindirizzamento per reindirizzare un file in un ciclo. In questo caso, stiamo reindirizzando $ 1, una variabile che contiene il nome del primo parametro della riga di comando che è passata allo script. Usando questo trucco, possiamo facilmente passare nel nome del file di dati che vogliamo lavorare lo script.
Copia e incolla lo script in un editor e salvalo con il nome file "script1.sh". Utilizzare il
chmod.
comando
Per renderlo eseguibile
.
CHMOD + X Script1.sh
Vediamo cosa fa il nostro script del file di testo Data2.txt e le backslashes contenute al suo interno.
./ script1.sh data2.txt
Ogni personaggio nella linea viene visualizzato Verbatim. Le backslashes non sono interpretate come personaggi di fuga. Sono stampati come personaggi regolari.
Passando la linea in una funzione
Stiamo ancora riecheggiando il testo sullo schermo. In uno scenario di programmazione del mondo reale, probabilmente stavamo per fare qualcosa di più interessante con la linea di testo. Nella maggior parte dei casi, è una buona pratica di programmazione per gestire l'ulteriore elaborazione della linea in un'altra funzione.
Ecco come potremmo farlo. Questo è "script2.sh".
Definiamo il nostro
Contatore
variabile come prima, e quindi definiamo una funzione chiamata
process_line ()
. La definizione di una funzione deve apparire
prima
La funzione viene prima chiamata nello script.
La nostra funzione sarà superata la nuova riga di testo di testo in ogni iterazione del
mentre
ciclo continuo. Possiamo accedere a tale valore all'interno della funzione utilizzando il
$ 1.
variabile. Se ci fossero due variabili passate alla funzione, potremmo accedere a tali valori usando
$ 1.
e
$ 2.
e così via per più variabili.
La W.
hile.
Loop è principalmente lo stesso. C'è solo un cambio all'interno del corpo del ciclo. Il
eco
la linea è stata sostituita da una chiamata al
process_line ()
funzione. Si noti che non è necessario utilizzare le parentesi "()" nel nome della funzione quando lo stai chiamando.
Il nome della variabile che tiene la linea di testo,
Linfromfile.
, è avvolto tra virgolette quando è passata alla funzione. Questo incontra le linee che hanno spazi in loro. Senza le virgolette, la prima parola è trattata come
$ 1.
Con la funzione, la seconda parola è considerata
$ 2.
, e così via. L'utilizzo di virgolette assicura che l'intera riga del testo sia gestita, del tutto, come
$ 1.
. Si noti che questo è
non
lo stesso
$ 1.
che detiene lo stesso file di dati superato allo script.
Perché
Contatore
è stato dichiarato nel corpo principale della sceneggiatura e non all'interno di una funzione, può essere referenziato all'interno del
process_line ()
funzione.
Copia o digita lo script sopra in un editor e salvalo con il nome file "script2.sh". Renderlo eseguibile con
chmod.
:
CHMOD + X Script2.sh
Ora possiamo eseguirlo e passare in un nuovo file di dati, "Data3.txt." Questo ha un elenco dei mesi in esso, e una riga con molte parole su di esso.
Gennaio febbraio marzo . . ottobre November \ nmore testo "Alla fine della linea" Dicembre
Il nostro comando è:
./ Script2.sh data3.txt
Le linee vengono lette dal file e passarono una per uno al
process_line ()
funzione. Tutte le linee vengono visualizzate correttamente, incluso quello dispari con lo backspace, le virgolette e più parole in esso.
I Building Blocks sono utili
C'è un treno di pensiero che dice che un idioma deve contenere qualcosa di unico per quella lingua. Non è una convinzione a cui mi iscrivo. Ciò che è importante è che faccia un buon uso della lingua, è facile da ricordare e fornisce un modo affidabile e robusto per implementare alcune funzionalità nel tuo codice.