2009-11-18 6 views
17

Tôi có một tập tin chứa chuỗiChuyển ra vào một mảng bash

ipAddress=10.78.90.137;10.78.90.149 

Tôi muốn đặt hai địa chỉ IP trong một mảng bash. Để đạt được điều đó tôi thử như sau:

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

Điều này dẫn đến giải nén các giá trị ổn nhưng vì một lý do kích thước của mảng được trả về như 1 và tôi nhận thấy rằng cả hai giá trị này được xác định là yếu tố đầu tiên trong mảng. Đó là

echo ${n[0]} 

lợi nhuận

10.78.90.137 10.78.90.149 

Làm thế nào để sửa lỗi này?

Cảm ơn sự giúp đỡ!

Trả lời

18

bạn có thực sự cần một mảng

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" 

nếu bạn muốn kiến để đưa vào mảng

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

@OP, liên quan đến phương pháp của bạn: set IFS của bạn đến một không gian

$ 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 

Ngoài ra, không có nhu cầu sử dụng rất nhiều công cụ. bạn chỉ có thể sử dụng awk, hoặc chỉ đơn giản là bash shell

#!/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[@]} 

đầu ra

$ 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 

trố mắt

$ 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

Các giá trị được sử dụng sau này trong tập lệnh. Nếu chúng được lưu trữ trong một mảng nó sẽ làm cho nó dễ dàng hơn để lặp lại và thực hiện các hoạt động khác trên chúng, do đó cần phải lưu trữ chúng trong một mảng. Phương pháp bạn mô tả sẽ giúp tôi. Cảm ơn! Bạn có thể chia sẻ suy nghĩ của bạn về lý do tại sao phương pháp tôi đang sử dụng không thành công? – calvinkrishy

+0

xem chỉnh sửa của tôi. một cách là đặt IFS. – ghostdog74

+1

Cảm ơn. Đã học một vài thủ thuật mới ngay hôm nay! – calvinkrishy

7

Cái này hoạt động:

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

EDIT: (cải thiện, phiên bản nestable theo Dennis)

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

Nếu bạn thay đổi backticks thành '$()' Tôi sẽ upvote bạn. –

+0

Điều này không hoạt động. BTW, không phải là biểu hiện giống như tôi đang sử dụng? Có sự khác biệt nào giữa việc sử dụng $() và '(dấu gạch chéo ngược) không? – calvinkrishy

+2

Nó hoạt động cho tôi. Đây là những gì nó sẽ giống như với '$()': 'n = ($ (grep -i ipaddress tên tập tin | cắt -d" = "-f2 | tr ';' ''))' - dấu ngoặc đơn bên ngoài làm cho nó vào một mảng. Tốt hơn nên sử dụng '$()' bởi vì chúng có thể được lồng vào nhau và dễ dàng hơn để trích dẫn và thoát ra ngay và chúng dễ đọc hơn: http://mywiki.wooledge.org/BashFAQ/082 –

1

Một biến thể của một chủ đề:

$ 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 

Nếu file không có nội dung nào khác, bạn có thể không cần số grep và bạn có thể đọc toàn bộ tệp.

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

dung dịch A Perl:

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

mà kiểm tra và loại bỏ các ký tự không mong muốn trong một thao tác.

0

Bạn có thể thực hiện việc này bằng cách sử dụng IFS trong bash.

  • Đầu tiên đọc dòng đầu tiên từ tệp.
  • Seoncd chuyển đổi thành một mảng với = làm dấu phân cách.
  • Chuyển đổi thứ ba giá trị thành một mảng với ; làm dấu phân cách.

Thats it !!!

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