2009-11-18 13 views
17

Ho un file contenente la stringareindirizzare l'output un allineamento bash

ipAddress=10.78.90.137;10.78.90.149 

mi piacerebbe inserire questi due indirizzi IP in un array di bash. Per raggiungere questo ho provato quanto segue:

n=$(grep -i ipaddress /opt/ipfile | cut -d'=' -f2 | tr ';' ' ') 

Ciò comporta estrarre i valori accettabile, ma per qualche ragione la dimensione della matrice viene restituito come 1 e noto che entrambi i valori sono identificati come il primo elemento array. Questo è

echo ${n[0]} 

rendimenti

10.78.90.137 10.78.90.149 

Come posso risolvere questo problema?

Grazie per l'aiuto!

risposta

18

Avete veramente bisogno di una serie

bash

$ ipAddress="10.78.90.137;10.78.90.149" 
$ IFS=";" 
$ set -- $ipAddress 
$ echo $1 
10.78.90.137 
$ echo $2 
10.78.90.149 
$ unset IFS 
$ echo [email protected] #this is "array" 

se si w formica di mettere in serie

$ a=([email protected]) 
$ echo ${a[0]} 
10.78.90.137 
$ echo ${a[1]} 
10.78.90.149 

@OP, per quanto riguarda il metodo: impostare le IFS ad uno spazio

$ IFS=" " 
$ n=($(grep -i ipaddress file | cut -d'=' -f2 | tr ';' ' ' | sed 's/"//g')) 
$ echo ${n[1]} 
10.78.90.149 
$ echo ${n[0]} 
10.78.90.137 
$ unset IFS 

Inoltre, non v'è alcuna necessità di utilizzare tanti strumenti. si può semplicemente utilizzare awk, o semplicemente la shell Bash

#!/bin/bash 
declare -a arr 
while IFS="=" read -r caption addresses 
do 
case "$caption" in 
    ipAddress*) 
     addresses=${addresses//[\"]/} 
     arr=(${arr[@]} ${addresses//;/ }) 
esac 
done < "file" 
echo ${arr[@]} 

uscita

$ more file 
foo 
bar 
ipAddress="10.78.91.138;10.78.90.150;10.77.1.101" 
foo1 
ipAddress="10.78.90.137;10.78.90.149" 
bar1 

$./shell.sh 
10.78.91.138 10.78.90.150 10.77.1.101 10.78.90.137 10.78.90.149 

gawk

$ n=($(gawk -F"=" '/ipAddress/{gsub(/\"/,"",$2);gsub(/;/," ",$2) ;printf $2" "}' file)) 
$ echo ${n[@]} 
10.78.91.138 10.78.90.150 10.77.1.101 10.78.90.137 10.78.90.149 
+0

I valori vengono utilizzati in seguito nello script. Se sono memorizzati in un array, renderebbe più semplice iterare ed eseguire altre operazioni su di essi, quindi è necessario memorizzarli in un array. Il metodo che descrivi dovrebbe aiutarmi. Grazie! Potresti per favore condividere le tue opinioni sul perché il metodo che sto usando sta fallendo? – calvinkrishy

+0

vedi la mia modifica. un modo è quello di impostare IFS. – ghostdog74

+1

Grazie. Ho imparato alcuni nuovi trucchi oggi! – calvinkrishy

7

Questo funziona:

n=(`grep -i ipaddress filename | cut -d"=" -f2 | tr ';' ' '`) 

EDIT: (migliorata, versione inseribile come da Dennis)

n=($(grep -i ipaddress filename | cut -d"=" -f2 | tr ';' ' ')) 
+1

Se si modifica l'apice inverso a '$()' Ti inviterò. –

+0

Questo non funziona. A proposito, non è l'espressione stessa di quella che sto usando? C'è qualche differenza tra l'uso di $() e '(backtick)? – calvinkrishy

+2

Funziona per me. Questo è come apparirebbe con '$()': 'n = ($ (grep -i ipaddress nomefile | cut -d" = "-f2 | tr ';' '' '))' - le parentesi esterne lo rendono in un array. È meglio usare '$()' perché possono essere annidati ed è più facile ottenere citazioni e fughe a destra e sono più leggibili: http://mywiki.wooledge.org/BashFAQ/082 –

1

Una variazione sul tema:

$ line=$(grep -i ipaddress /opt/ipfile) 
$ saveIFS="$IFS" # always save it and put it back to be safe 
$ IFS="=;" 
$ n=($line) 
$ IFS="$saveIFS" 
$ echo ${n[0]} 
ipAddress 
$ echo ${n[1]} 
10.78.90.137 
$ echo ${n[2]} 
10.78.90.149 

Se il file non ha altri contenuti, potrebbe non essere necessario il grep e potresti leggere l'intero file.

$ saveIFS="$IFS" 
$ IFS="=;" 
$ n=$(</opt/ipfile) 
$ IFS="$saveIFS" 
1

soluzione A Perl:

n=($(perl -ne 's/ipAddress=(.*);/$1/&& print' filename)) 

quali test e rimuove i caratteri indesiderati in una sola operazione.

0

È possibile farlo utilizzando IFS in bash.

  • Leggere innanzitutto la prima riga dal file.
  • Seoncd convertirlo in un array con = come delimitazione.
  • In terzo luogo convertire il valore in un array con ; come delimitazione.

Questo è tutto !!!

#!/bin/bash 
IFS='\n' read -r lstr < "a.txt" 
IFS='=' read -r -a lstr_arr <<< $lstr 
IFS=';' read -r -a ip_arr <<< ${lstr_arr[1]} 
echo ${ip_arr[0]} 
echo ${ip_arr[1]}