用基于该字符串的变量替换bash中的字符串[重复]

Posted

技术标签:

【中文标题】用基于该字符串的变量替换bash中的字符串[重复]【英文标题】:Replace a string in bash, with a variable based on that string [duplicate] 【发布时间】:2016-09-13 15:29:26 【问题描述】:

我正在尝试解析 IP 地址的文件,然后将它们替换为 1 for 1 映射的 IP 地址。例如,查找 1.1.1.1 的所有实例并将其替换为 100.100.1.1,并查找 5.5.5.5 的所有实例并将其替换为 100.100.5.5。可能有数千个 IP,因此我不想使用静态 sed 命令解析每个替换的文件。

我正在尝试为此使用 关联数组,但我做不到。

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 中进行替换?我已经尝试了一些带有 quotes 的变体,并提前构建了一个仍然依赖于 '\1' 的 variable 但它要么失败,要么只返回 变量的文字输出。我不知道是否有比 sed 更好的工具。 我也尝试使用变量而不是数组,但遇到了同样的问题。

【问题讨论】:

您正在使用ip_\1 动态调用索引。也就是说,使用捕获的组。这是不可能的,因为你现在正在这样做,但可能需要使用 sed e 标志来执行东西。例如,请参阅 this answer by anubhava 以获取一个很好的示例。 Perl 支持替换和关联数组(哈希)。我会用它来代替 sed。 感谢@jil 的链接,我还没有设法让链接的 awk 解决方案正常工作,但我没有使用 awk 的经验,所以我无法轻易判断这是否能解决问题。从我的阅读来看,它可能不会。 不要忘记,您可以使用数组创建多个表达式,使用 -e 选项和 sed 并根据需要更改任意数量的 IP 对。如果文件有 1000 行,您可以想象一次调用就可以完成。 Replace a field with values specified in another file 有 sedawkperl 方法来做到这一点。 【参考方案1】:

POSIX shell 脚本,输入是 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

注意:效率低下,它会为 testfile.txt 的每一行重新读取至少一行 replacements.txt,但这确实允许替换列表大于 bash 的可用内存。

【讨论】:

以上是关于用基于该字符串的变量替换bash中的字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章

sed 用 Bash 变量替换

bash shell参数展开(Shell Parameter Expansion):替换变量(variable)中的字符串

用 cURL 命令中的变量替换字符串 [重复]

如何在bash中将空格替换为新行[重复]

用bash中的另一个字符串替换结束括号

bash:字符串查找