Ripeti ciclicamente il file delineato nella scheda nello script bash


18

Ecco cosa ho finora:

#!/bin/bash
while read line; do
        DB=$(echo $line | cut -f1)
        USER=$(echo $line | cut -f2)
        PASS=$(echo $line | cut -f3)
        echo DB=$DB USER=$USER PASS=$PASS
done < users.txt

E un esempio del file di input:

drupal_1    drupal1 tmmjXSWL
drupal_2    drupal2 FHiJSYHM
drupal_3    drupal3 b7bFNj06
drupal_4    drupal4 0AaV62EL

E output dallo script:

DB=drupal_1 drupal1 tmmjXSWL USER=drupal_1 drupal1 tmmjXSWL PASS=drupal_1 drupal1 tmmjXSWL
DB=drupal_2 drupal2 FHiJSYHM USER=drupal_2 drupal2 FHiJSYHM PASS=drupal_2 drupal2 FHiJSYHM
DB=drupal_3 drupal3 b7bFNj06 USER=drupal_3 drupal3 b7bFNj06 PASS=drupal_3 drupal3 b7bFNj06

Per qualche motivo, ogni variabile è impostata su tutta la riga. Quando uso echo users.txt | cut -f1dalla riga di comando, restituisce il token bene.

Risposte:


6

Cosa ne pensi di questo?

$ awk '{print "DB="$1"\tUSER="$2"\tPASS="$3}' users.txt
DB=drupal_1 USER=drupal1    PASS=tmmjXSWL
DB=drupal_2 USER=drupal2    PASS=FHiJSYHM
DB=drupal_3 USER=drupal3    PASS=b7bFNj06
DB=drupal_4 USER=drupal4    PASS=0AaV62EL

Non so dire se hai un problema da risolvere o ti stai chiedendo un problema più teorico.


Grazie, funziona. Sto cercando di scrivere uno script per creare oltre 40 installazioni Drupal su un server per una lezione che sto insegnando. Ho degli script per configurare i DB e i file, questo è un pezzo dello script che metterà tutto insieme. Il problema con il mio codice era che la riga $ trasformava le schede in spazi mentre veniva analizzato. $(echo $line | cut -d" " -f1)funziona anche.
mortona42,

fallisce per me se qualcuno dei campi contiene spazi
v01pe

21

Il problema è nel comando echo $line. Dal momento che non ci sono virgolette in giro $line, la shell esegue la suddivisione delle parole su di essa, quindi interpreta ogni parola come un modello globbing. Provalo con

a='*.txt foo'
ls $a

Nel tuo caso, le schede separano le parole, che diventano quindi argomenti separati per echo. Il echocomando stampa i suoi argomenti separati da uno spazio. Quindi cutfinisce per ricevere campi delimitati da spazi anziché campi delimitati da tabulazioni.

Metti sempre virgolette doppie tra sostituzioni variabili $fooe sostituzioni di comandi$(foo) (a meno che tu non capisca perché è necessario lasciarle fuori e perché è ok farlo). echo "$line"funzionerebbe qui, ma è un modo complicato di fare ciò che proponi.

Mantenendo il tuo approccio all'analisi nella shell, puoi fare in modo che il readcomando analizzi l'input nei campi.

while read DB USER PASS; do
  echo "DB=$DB USER=$USER PASS=$PASS"
done <users.txt

readdivide i campi separati da caratteri nel valore della IFSvariabile, che consiste in uno spazio e una scheda (più una nuova riga, che non può verificarsi all'interno di una linea) per impostazione predefinita. Per dividere solo in schede, impostare prima IFSsu una singola scheda. Si noti che le schede iniziali e finali vengono ignorate e le schede consecutive vengono conteggiate come singole.

readconsidera \un personaggio speciale: una barra rovesciata seguita da una nuova riga viene ignorata; \\diventa una singola barra rovesciata. Se si desidera evitare questo comportamento, passare l' -ropzione.


15
+1. Per impostare IFS su un carattere di tabulazione in bash:IFS=$'\t'
glenn jackman,
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.