2016-05-17 109 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的可用内存。