# [SCRIPT - OT] Leggere info da file di testo "multicolon

## berus

Ciao. Qualcuno riesce a crearmi uno scriptino bash (in realtà mi servirebbe csh ... poi cercherò di modificarlo) che legga un file così composto:

```
macchina directory utente password qualcosa1 qualcosa2

macchina directory,directory1,directory6 utente password qualcosa1 qualcosa2
```

oppure (dipende cosa risulta più facile)

```
macchina,directory,utente,password,qualcosa1,qualcosa2

macchina,directory|directory1|directory6,utente,password, qualcosa1,qualcosa2
```

 e permetta di utilizzare le variabili in un comando tipo 

```
/opt/samba/bin/smbtar -v -s $macchina -x $directory -u $utente -p $password -t $qualcosa1
```

Capito  :Shocked:  ? Grazie

----------

## xchris

capito  :Smile: 

ci sono diversi modi...

1 - sed/awk

2 - cut

ti illustro il secondo che e' + semplice a mio avviso

```

cat file | cut -d" " -f1

-f2

-f3

....

```

ciao

----------

## fedeliallalinea

Script

```
#!/bin/sh

STRING="macchina directory,directory1,directory6 utente password qualcosa1 qualcosa2"

DONE=""

while $DONE

do

  ARG=`echo $STRING | awk -F" " '{print $1}'`

  if [ -z "$ARG" ]

  then

    DONE="exit"

  else

    STRING=`echo $STRING | awk -F$ARG '{print $2}'`

    echo $ARG

  fi

done
```

Output

```
$ sh prova 

macchina

directory,directory1,directory6

utente

password

qualcosa1

qualcosa2
```

----------

## berus

Grazie! 

Purtroppo mi serve qualcosa di complicato..  :Very Happy: 

Ho dimenticato di dirvi che devo anche "esplodere" la parte con le virgole (non nel caso di smbtar).

Se volessi omettere qualche "variabile" con gli spazi non posso giusto? Una cosa del tipo

```
macchina,directory|directory1|directory6,utente,password,qualcosa1,qualcosa2

macchina,directory|directory1|directory6,utente,,qualcosa1,qualcosa2
```

 Non sono sicuro di dover adottare questa strada, però..

----------

## fedeliallalinea

 *berus wrote:*   

> Ho dimenticato di dirvi che devo anche "esplodere" la parte con le virgole (non nel caso di smbtar).

 

In che senso quelle delle directory? Poi metti tutto quello che vorresti fare

----------

## berus

Si esatto.. Vorrei splittare la stringa delle directory. Ma potrebbe non essere solo quella da splittare quindi credo serve un if che valuti se la stringa contiene o meno delle virgole (o pipe). 

Poi.. se volessi omettere qualche parametro (ad esempio come il /etc/passwd che usa i : .. : :Smile:  devo per forza utilizzare altri caratteri per dividere i parametri... In pratica: non posso usare due spazi per dividere il primo ed il terzo parametro (escludendo il secondo), giusto?

Alla fine della fiera devo creare questo comando

```
/opt/samba/bin/smbtar -v -s $macchina -x $directory -u $utente -p $password -t $qualcosa1
```

in questo modo

```
/opt/samba/bin/smbtar -v $VAR1$VAR2$VAR3$VAR4$VAR5
```

dove gli $ARG* saranno così composti (se è valido il discorso di ARG come array)

```
VAR1="-s $ARG[1] "

VAR2="-x $ARG[2] "

VAR3="-u $ARG[3] "

VAR4="-p $ARG[4] "

VAR5="-t $ARG[5]"
```

Inoltre ci dovrebbe essere un if che valuta se $ARG[*] è vuoto ed allora crea VAR*=""

Stop  :Wink: 

Grazie

----------

## gutter

Vediamo se ho capito che devi fare:

```

#!/bin/bash

## Parse string:

## macchina directory,directory1,directory6 utente password qualcosa1 qualcosa2

  machine=$1

  echo $machine

  # Parse directory

  OLD_IFS=$IFS ; IFS=","

  (( n = 1))

  shift

  for current in $1

    do

    eval dir$n=$current

    echo  `eval echo '$dir'$n`

    (( n++ ))

  done 

  

  IFS=$OLD_IFS

  shift

  user=$1

  echo $user

  shift

  passwd=$1

  echo $passwd

  

  # Parse others

  (( n = 1 ))

  shift

 for current in $@

   do

   eval other$n=$current

   echo  `eval echo '$other'$n`

   (( n++ ))

   shift

 done  

```

Lancialo con:

```

./script.sh macchina directory,directory1,directory6 utente password qualcosa1 qualcosa2

```

Edit Wed Mar 16 19:01:19 CET 2005: Aggiornato con l'aiuto di xchris  :Wink: 

----------

## berus

Ciao! Si diciamo che il risultato è quello. L'unica cosa che mi lascia un po' perplesso è: a priori con questo script devo sapere quale argomento è da "suddividere".. In realtà protrebbe essere directory come qualcosa1, qualcosa2 o altro*.

E poi devo per forza utilizzare un file con la stringa.. quindi credo di dover passare tramite cat, awk, ...  :Crying or Very sad: 

----------

## gutter

 *berus wrote:*   

> Ciao! Si diciamo che il risultato è quello. L'unica cosa che mi lascia un po' perplesso è: a priori con questo script devo sapere quale argomento è da "suddividere".. In realtà protrebbe essere directory come qualcosa1, qualcosa2 o altro*.
> 
> 

 

Qeusto script fa il parsind della stringa anche se directory è una sola mentre dopo hai qualcosa1,qualcosa2,qualcosa3. Fa qualche prova  :Wink: 

 *berus wrote:*   

> 
> 
> E poi devo per forza utilizzare un file con la stringa.. quindi credo di dover passare tramite cat, awk, ... 

 

Questo non mi sembra un problema  :Wink:  Basta semplicemente fare qualche modifica allo script  :Wink:  o utilizzare set per settare i parametri posizionali dello script  :Very Happy: 

----------

## berus

 *gutter wrote:*   

> Qeusto script fa il parsind della stringa anche se directory è una sola mentre dopo hai qualcosa1,qualcosa2,qualcosa3. Fa qualche prova 

 

```
./script.sh macchina directory,directory1,directory6 utente password qualcosa1a,qualcosa1b qualcosa2
```

```
macchina

directory

directory1

directory6

utente

password

qualcosa1a,qualcosa1b

qualcosa2
```

Invece dovrei dividere anche qualcosa1*...  :Rolling Eyes: 

Per questo script posso arraggiarmi dicendo che solo $directory e $qualcosa1 possono avere più valori.. ma io l'avevo pensato con un if che controllasse la presenza o meno della virgola (o qualsiasi altro segno di separazione).

 *gutter wrote:*   

> Questo non mi sembra un problema  Basta semplicemente fare qualche modifica allo script  o utilizzare set per settare i parametri posizionali dello script 

  Adesso cerco di leggermi un po' di man.. però mi fai un esempio veloce per il set? Grazie

----------

## gutter

Scusami ma forse nonho capito io: alla fine mi stai diceno che è possibile che i campi che abbiano le virgole siano più di uno e non si sa dove???

----------

## berus

Si  :Rolling Eyes:  .. (non solo per questo script)

No  :Wink:   .. (se facciamo riferimento solo a questo script per il smbtar)

Però a pensarci bene mi sto complicando la vita per niente. In fondo devo sapere quali e quanti parametri DEVO passare. Io non ho chiesto niente..  :Embarassed: 

Diciamo che provo a preparare tutto lo script e magari poi mi aiutate a correggerlo e migliorarlo.. vero? CiauuuuLast edited by berus on Thu Mar 17, 2005 9:27 am; edited 1 time in total

----------

## gutter

Non è difficile realizzare una cosa del genere basta mettere qualche if e dentro gli if i for che ho scritto devi fare solo delle piccole nodifiche  :Wink: .

Se hai bisogno di aiuto fammi sapere  :Smile: 

----------

## berus

Mi sono già perso  :Embarassed: 

Una cosa tipo questa è corretta?

```
for M in `cat ./lista-pc-smbtar`; do

echo $M 

done

```

Non proprio visto che stampa

```
valore1riga1

valore1riga2

valore1riga3

valore2riga1

valore2riga2

valore2riga3

[...]
```

Invece mi aspetto (il file è così)

```
valore1riga1 valore2riga1 valore3riga1

valore1riga2 valore2riga2 valore3riga2

[...]
```

Vi spiego cosa devo fare in questo punto..

```
for $VAR (leggo il file riga per riga)

ipotizzando di usare awk su $VAR

set della var PC=$1

set della var USER=$2

set della var PASS=$3

[...]

vari controlli if e se necessario divido la var (directory...)

pingo PC

if di controllo

lancio smbtar $PC$USER$PASS$*

eventuale log
```

Ho provato e riprovato ma ottengo sempre dei risultati pessimi.  :Evil or Very Mad:  [/b]

----------

## gutter

Sei riuscito a non farmi capire più che devi fare  :Wink: 

Io sono disposto ad aiutarti ma mi devi fare un esempio completo dall'inizio alla fine  :Very Happy: 

----------

## berus

 :Cool: 

E' che andando avanti con i lavori ho perso la retta via. Cerco di semplificare al massimo..

Obiettivo: script che girerà su SUN (in cron) che faccia il backup di alcuni pc con cartelle condivise per mezzo del comando smbtar. Il comando smbtar dovrà avere questa sintassi (+ o - .. sarà necessario anche l'opzione per escludere alcune cartelle)

```
smbtar -s $PC -u $USER -p $PASS -x $SHARE -t - | gzip -c > $PC.tar.gz
```

Il comando andrà lanciato senza opzioni.

Due file: 

script per /bin/sh

file di "configurazione"Il file di configurazione è così composto

```
pc1 utente1 pass1 dir1,dir2,dir3 

pc1 utente1 pass1 dir1,dir1a,dir1b

pc2 utente2 pass2 dir2

pc3 utente3 pass3 dir3,dir3a dir_da_escludere3

[...]
```

Adesso spiego velocemente perchè devo scappare: leggo il file di configurazione e per ogni riga setto le variabili $PC=pc1, $USER=utente1 e così via (effettuando i controlli e le esplosioni della stringa.. nel caso delle directory ad esempio). Provo a pingare $PC se ho successo lancio il comando smbtar precedentemente composto e magari faccio un minimo di log..

Grazie

----------

## gutter

E mi pare che lo script si avvicini molto a quello che serve a te  :Wink: 

Non capisco dove sta il problema  :Very Happy: 

----------

## berus

Ad esempio come faccio a fare il parsing del famoso file di configurazione, senza dover passare gli argomenti da linea di comando?  :Embarassed: 

Capisco che nel cron potrei mettere un file che a sua volta contenga l'intero comando ma preferirei avere questo file.  :Sad: 

Buongiorno!  :Wink: 

----------

## fedeliallalinea

Le directory come vanno messe in smbtar se piu' di una? e i qualcosa come vengono messi se piu' di uno?

----------

## berus

Oops, ero convinto di poter utilizzare più share nello stesso comando. Ma non ne trovo traccia.  :Question:   :Confused: 

Facciamo l'esempio con una e una per adesso.  :Rolling Eyes: 

----------

## fedeliallalinea

Si ok ma per i qualcosa1,qualcosa2? Come li metti se piu' di uno?

----------

## berus

Ad esempio  così (se sono le cartelle da escludere)

```
 -X /win95 /win98
```

Ed a pensarci bene forse funziona anche con le directory da backuppare..  :Very Happy: 

----------

## gutter

 *berus wrote:*   

> Ad esempio come faccio a fare il parsing del famoso file di configurazione, senza dover passare gli argomenti da linea di comando? 
> 
> 

 

Ad esempio usando il comando read  :Wink: 

----------

## berus

```
     while read pc user pass dir excl

     do     

             echo "$pc -  $user -  $pass -  $dir -  $excl"

     done < lista-pc-smbtar
```

Non si finisce mai d'imparare.. Questo fa al caso mio.  :Wink:  Proviamo così.

----------

## gutter

 *berus wrote:*   

> Non si finisce mai d'imparare.. 

 

Siamo qua tutti per questo  :Very Happy: 

----------

## berus

Ciao, rieccomi qua. Sono riuscito a continuare un po' i lavori solo negli ultimi 5 minuti. Va tutto abbastanza bene a parte l'explode (uso php di solito) degli array creati da read. Se ho la mia varibile $SHARE come faccio a controllare se è presente la , (virgola) e se fosse così come faccio ad esplodere tale variabile? edit: Più che esplodere mi interessa avere la variabile nella forma "dir1 dir2 dir3" Ho provato a modificare 

```
  OLD_IFS=$IFS ; IFS=","

  (( n = 1))

  shift

  for current in $1

    do

    eval dir$n=$current

    echo  `eval echo '$dir'$n`

    (( n++ ))

  done

 

  IFS=$OLD_IFS
```

ma funziona solo con gli argomenti da linea di comando e non con le variabili create dallo script.. mi è parso di capire che sia così  :Rolling Eyes: 

----------

## gutter

Non funziona con tutto basta solo apportare delle modifiche  :Wink: 

Ma non volevi delle variabili separate ?!?

----------

## berus

Si volevo avere le variabili separate.. o sotto forma di array almeno. Però visto che non funzionava ho optato per la "soluzione degli spazi" che ho creato in questo modo

```
PROVA=`echo "dir1,dir2,dir3" | tr ',' ' '`

echo $PROVA
```

Non so se è la soluzione migliore ma per adesso funziona.

----------

## gutter

Basta che funzioni  :Wink: .

----------

