web-dev-qa-db-ja.com

出力をbash配列にリダイレクトします

文字列を含むファイルがあります

ipAddress=10.78.90.137;10.78.90.149

これらの2つのIPアドレスをbash配列に配置したいと思います。それを達成するために、私は以下を試しました:

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

これにより、値は正常に抽出されますが、何らかの理由で配列のサイズが1として返され、両方の値が配列の最初の要素として識別されていることがわかります。あれは

echo ${n[0]}

戻り値

10.78.90.137 10.78.90.149

これを修正するにはどうすればよいですか?

助けてくれてありがとう!

19
calvinkrishy

本当に配列が必要ですか

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 $@ #this is "array"

配列に入れたい場合

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

@OP、メソッドに関して:IFSをスペースに設定します

$ 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

また、それほど多くのツールを使用する必要はありません。 awk、または単に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[@]}

出力

$ 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
20
ghostdog74

これは機能します:

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

編集:(デニスによる改良された、ネスト可能なバージョン)

n=($(grep -i ipaddress filename | cut -d"=" -f2 | tr ';' ' '))
8
Joy Dutta

テーマのバリエーション:

$ 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

ファイルに他の内容がない場合は、grepは不要であり、ファイル全体を読み取ることができます。

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

Perlソリューション:

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

これは、1回の操作で不要な文字をテストして削除します。

1
J. A. Faucett

これを行うには、IFSbashを使用します。

  • まず、ファイルから最初の行を読み取ります。
  • Seoncdは、それを=を区切り文字として持つ配列に変換します。
  • 3番目に、値を;を区切り文字として配列に変換します。

それでおしまい !!!

#!/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]}
0
rashok