GNU/Linux >> Linux Esercitazione >  >> Linux

Introduzione alla programmazione Linux Bash:5 suggerimenti per i loop `for`

Ogni amministratore di sistema ha probabilmente alcune abilità che ha appreso nel corso degli anni che può indicare e dire:"Questo ha cambiato il mio mondo". Quell'abilità, o quel bit di informazione, o quella tecnica hanno semplicemente cambiato il modo in cui faccio le cose. Per molti di noi, quella cosa è in loop in Bash. Esistono altri approcci all'automazione che sono sicuramente più robusti o scalabili. La maggior parte di essi non è paragonabile alla semplicità e alla pronta usabilità di for loop, però.

Se vuoi automatizzare la configurazione di migliaia di sistemi, probabilmente dovresti usare Ansible. Tuttavia, se stai cercando di rinominare un migliaio di file o di eseguire lo stesso comando più volte, allora for loop è sicuramente lo strumento giusto per il lavoro.

[ Potrebbe piacerti anche: Mastering loop con i modelli Jinja in Ansible ]

Se hai già un background di programmazione o di scripting, probabilmente hai familiarità con cosa for i loop fanno. Se non lo sei, cercherò di scomporlo in un inglese semplice per te.

Il concetto di base è:PER un determinato insieme di elementi, FAI una cosa.

L'insieme di elementi specificato può essere un insieme letterale di oggetti o qualsiasi cosa che Bash possa estrapolare in un elenco. Ad esempio, il testo estratto da un file, l'output di un altro comando Bash o i parametri passati tramite la riga di comando. Anche convertire questa struttura di loop in uno script Bash è banale. In questo articolo, ti mostriamo alcuni esempi di come un for loop può farti sembrare un eroe della riga di comando, quindi prendiamo alcuni di questi esempi e li inseriamo in uno script Bash più strutturato.

Struttura di base del ciclo for

Per prima cosa, parliamo della struttura di base di un for loop, e poi entreremo in alcuni esempi.

La sintassi di base di un for ciclo è:

for <variable name> in <a list of items>;do <some command> $<variable name>;done;

Il nome della variabile sarà la variabile che specifichi in do sezione e conterrà l'elemento nel ciclo in cui ti trovi.

L'elenco di elementi può essere qualsiasi cosa che restituisca uno spazio o un elenco separato da una nuova riga.

Ecco un esempio:

$ for name in joey suzy bobby;do echo $name;done

È così semplice e non c'è molto da fare lì, ma ti fa iniziare. La variabile $nome conterrà l'elemento nell'elenco su cui sta attualmente operando il ciclo e una volta che il comando (o comandi) nel do vengono eseguite, il ciclo si sposterà all'elemento successivo. Puoi anche eseguire più di un'azione per ciclo. Qualsiasi cosa tra do e done sarà eseguito. I nuovi comandi richiedono solo un ; delimitandoli.

$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby

Ora per un po' di reale esempi.

Rinominare i file

Questo ciclo prende l'output del comando Bash ls *.pdf ed esegue un'azione su ciascun nome file restituito. In questo caso, aggiungiamo la data odierna alla fine del nome del file (ma prima dell'estensione del file).

for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done

Per illustrare, esegui questo ciclo in una directory contenente questi file:

file1.pdf
file2.pdf
...
fileN.pdf

I file verranno rinominati in questo modo:

file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf

In una directory con centinaia di file, questo ciclo consente di risparmiare una notevole quantità di tempo nel rinominarli tutti.

Estrarre elenchi di elementi

Immagina di avere un file che vuoi scp a più server. Ricorda che puoi combinare il for loop con altre funzionalità di Bash, come l'espansione della shell, che consente a Bash di espandere un elenco di elementi che si trovano in una serie. Questo può funzionare per lettere e numeri. Ad esempio:

$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10

Supponendo che i tuoi server siano denominati in una sorta di schema come web0 , web1 , web2 , web3 , puoi fare in modo che Bash ripeta la serie di numeri in questo modo:

$ for i in web{0..10};do scp somefile.txt ${i}:;done;

Questo scorrerà attraverso web0 , web1 , web2 , web3 e così via, eseguendo il comando su ogni elemento.

Puoi anche definire alcune iterazioni. Ad esempio:

$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c

Puoi anche combinare le iterazioni. Immagina di avere due data center, uno negli Stati Uniti, un altro in Canada, e la convenzione di denominazione del server identifica in quale data center viveva una coppia di server HA. Ad esempio, web-us-0 sarebbe il primo server web nel data center degli Stati Uniti, mentre web-ca-0 sarebbero web 0 controparte nel data center CA. Per eseguire qualcosa su entrambi i sistemi, puoi usare una sequenza come questa:

$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3

Nel caso in cui i nomi dei tuoi server non siano facili da scorrere, puoi fornire un elenco di nomi a for ciclo:

$ cat somelist
first_item
middle_things
foo
bar
baz
last_item

$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item

Nidificazione

Puoi anche combinare alcune di queste idee per casi d'uso più complessi. Ad esempio, immagina di voler copiare un elenco di file sui tuoi server web che seguono la convenzione di denominazione numerata che hai utilizzato nell'esempio precedente.

Puoi farlo iterando un secondo elenco basato sul tuo primo elenco attraverso cicli nidificati. Questo diventa un po' difficile da seguire quando lo fai come una battuta, ma può sicuramente essere fatto. Il tuo for annidato loop viene eseguito ad ogni iterazione del genitore for ciclo continuo. Assicurati di specificare nomi di variabili diversi per ogni ciclo.

Per copiare l'elenco dei file file1.txt, file2.txt, e file3.txt ai server web, usa questo ciclo annidato:

$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3

Rinomina più creatività

Potrebbero esserci altri modi per farlo, ma ricorda, questo è solo un esempio di cose che puoi fare con un for ciclo continuo. Che cosa succede se hai una montagna di file con un nome simile a FILE002.txt e vuoi sostituire FILE con qualcosa come TESTO . Ricorda che oltre a Bash stesso, hai anche altri strumenti open source a tua disposizione, come sed , grep , e altro ancora. Puoi combinare questi strumenti con il for loop, in questo modo:

$ ls FILE*.txt
FILE0.txt  FILE10.txt  FILE1.txt  FILE2.txt  FILE3.txt  FILE4.txt  FILE5.txt  FILE6.txt  FILE7.txt  FILE8.txt  FILE9.txt

$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done

$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory

$ ls TEXT*.txt
TEXT0.txt  TEXT10.txt  TEXT1.txt  TEXT2.txt  TEXT3.txt  TEXT4.txt  TEXT5.txt  TEXT6.txt  TEXT7.txt  TEXT8.txt  TEXT9.txt

Aggiunta di un ciclo for a uno script Bash

Esecuzione di for i loop direttamente sulla riga di comando sono fantastici e ti fanno risparmiare una notevole quantità di tempo per alcune attività. Inoltre, puoi includere for loop come parte dei tuoi script Bash per maggiore potenza, leggibilità e flessibilità.

Ad esempio, puoi aggiungere l'esempio di ciclo nidificato a uno script Bash per migliorarne la leggibilità, in questo modo:

$ vim copy_web_files.sh
# !/bin/bash

for i in file{1..3};do
  for x in web{0..3};do
    echo "Copying $i to server $x"
    scp $i $x
  done
done

Quando salvi ed esegui questo script, il risultato è lo stesso dell'esecuzione dell'esempio di ciclo nidificato sopra, ma è più leggibile, inoltre è più facile da modificare e mantenere.

$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3

Puoi anche aumentare la flessibilità e la riutilizzabilità del tuo for loop includendoli negli script Bash che consentono l'input di parametri. Ad esempio, per rinominare file come nell'esempio Rinomina più creatività sopra consentendo all'utente di specificare il suffisso del nome, utilizzare questo script:

$ vim rename_files.sh
# !/bin/bash

source_prefix=$1
suffix=$2
destination_prefix=$3

for i in $(ls ${source_prefix}*.${suffix});do
  mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done

In questo script, l'utente fornisce il prefisso del file di origine come primo parametro, il suffisso del file come secondo e il nuovo prefisso come terzo parametro. Ad esempio, per rinominare tutti i file che iniziano con FILE , di tipo .txt a TESTO , esegui lo script in questo modo:

$ ls FILE*.txt
FILE0.txt  FILE10.txt  FILE1.txt  FILE2.txt  FILE3.txt  FILE4.txt  FILE5.txt  FILE6.txt  FILE7.txt  FILE8.txt  FILE9.txt

$ bash rename_files.sh FILE txt TEXT

$ ls TEXT*.txt
TEXT0.txt  TEXT10.txt  TEXT1.txt  TEXT2.txt  TEXT3.txt  TEXT4.txt  TEXT5.txt  TEXT6.txt  TEXT7.txt  TEXT8.txt  TEXT9.txt

È simile all'esempio originale, ma ora gli utenti possono specificare altri parametri per modificare il comportamento dello script. Ad esempio, per rinominare tutti i file che ora iniziano con TEXT a NUOVO , usa quanto segue:

$ bash rename_files.sh TEXT txt NEW

$ ls NEW*.txt
NEW0.txt  NEW10.txt  NEW1.txt  NEW2.txt  NEW3.txt  NEW4.txt  NEW5.txt  NEW6.txt  NEW7.txt  NEW8.txt  NEW9.txt

[ Un corso gratuito per te:Panoramica tecnica su virtualizzazione e migrazione dell'infrastruttura. ] 

Conclusione

Si spera che questi esempi abbiano dimostrato la potenza di un for loop alla riga di comando di Bash. Puoi davvero risparmiare molto tempo ed eseguire attività in un modo meno soggetto a errori con i loop. Solo stai attento. I tuoi loop faranno ciò che chiedi loro, anche se chiedi loro di fare qualcosa di distruttivo per sbaglio, come creare (o eliminare) volumi logici o dischi virtuali.

Ci auguriamo che Bash for i loop cambiano il tuo mondo nello stesso modo in cui hanno cambiato il nostro.


Linux
  1. Come scrivere un ciclo in Bash

  2. Analisi della cronologia di Bash in Linux

  3. 12 Esempi di Bash For Loop per gli script della tua shell Linux

  4. Bash di Linux. ciclo for e funzione, per sommare numeri

  5. Convertitore di versione PDF per Linux

Bash For Loop

Bash fino a Loop

Comando della cronologia in Linux (Cronologia di Bash)

Un'introduzione a Vivaldi Browser su Linux

5 consigli per padroneggiare Linux

20 suggerimenti per la programmazione Killer Perl per principianti su sistemi operativi UNIX/Linux