2016-05-17 152 views
0

我試圖解析IP地址的文件,然後用1代替1映射的IP地址。例如,查找1.1.1.1的所有實例,並將其替換爲100.100.1.1和5.5.5.5的所有實例,並將其替換爲100.100.5.5。可能有數千個IP,因此我不想使用靜態的命令解析文件中的每個替換。在bash中替換字符串,其中基於該字符串的變量

我想爲此使用關聯數組,但我不盡人意。

echo "1.1.1.1 5.5.5.5" > testfile.txt 
declare -A testarray 
testarray[ip_1.1.1.1]="100.100.1.1" 
testarray[ip_5.5.5.5]="100.100.5.5" 
sed -r "s/(([0-9]{1,3}\.){3}[0-9]{1,3})/${testarray[ip_\1]}/g" testfile.txt 

在變量內部使用捕獲組不起作用。然而,直接使用文本呢。

sed -r "s/(([0-9]{1,3}\.){3}[0-9]{1,3})/${testarray[ip_1.1.1.1]}/g" testfile.txt 
100.100.1.1 100.100.1.1 

當然這將替換所有的IP與100.100.1.1,我想基於陣列關聯替換。

是否有任何方法拍攝捕捉組並在變量中使用它來替換bash?我已經嘗試了一些變種報價以及提前仍然依賴於「\ 1」建設變量但它要麼失敗,或者只是返回變量字面輸出。我不知道是否有比sed更好的工具。 我也嘗試使用變量而不是數組,但我遇到了同樣的問題。

+0

您正在用'ip_ \ 1'命名dinamically。也就是說,使用捕獲的組。這是不可能的,因爲你現在正在做,但可能需要使用'sed''''標誌來執行。看一個很好的例子[anubhava的這個答案](http://stackoverflow.com/a/34080390/1983854)。 – fedorqui

+2

Perl支持替換和關聯數組(散列)。我會用它代替sed。 – choroba

+0

感謝鏈接@jil,我還沒有設法讓鏈接的awk解決方案工作,但我沒有使用Awk的經驗,所以我不能輕易分辨這是否能解決問題。從我的閱讀中,它可能不會。 – suretass

回答

0

POSIX外殼腳本​​,輸入是TESTFILE.TXT,逗號分隔 「從爲」 對在replacements.txt

echo 1.1.1.1 100.100.1.1 ,5.5.5.5 100.100.5.5 | tr ',' '\n' > replacements.txt 
echo "1.1.1.1 6.7.8.9 5.5.5.5" | tr ' ' '\n' > testfile.txt 

while read x ; do 
    while read a b ; do 
     if [ $a = $x ] ; then 
      x=$b 
      break 
     fi 
    done < replacements.txt 
    echo $x 
done < testfile.txt 

輸出:

100.100.1.1 
6.7.8.9 
100.100.5.5 

注:低效,它重新讀取至少一行replacements.txt對於每行testfile.txt,但是確實允許替換列表大於bash的可用內存。