如何根据 Bash 中的子字符串检查一个字符串是否等于另一个字符串
How to check if a string is equal to another string based in a substring in Bash
我正在尝试执行以下操作:
我有一个名为 testing.txt 的文件,每次 IP 地址或地址根据名称(test1ip、test2ip)更改时我都想更新它:
127.0.0.1 localhost
somotherrandomip testing
192.168.0.36 test1ip
192.168.0.37 test2ip
这是我试过的。
#!/bin/bash
array=(
"192.168.0.34 test1ip"
"192.168.0.35 test2ip"
)
for i in "${array[@]}"; do
if ! grep -Fxq "$i" testing.txt
then
echo "ip-name=$i is not present, so adding it in testing.txt file"
echo "$i" >> testing.txt
else
echo "ip-name=$i is present in file, so nothing to do"
fi
done
但是,如果找不到该行,此脚本会附加一个全新的行。我想要实现的是,如果找到 test1ip 或 test2ip 但 ip 地址发生变化,则覆盖该行。
预期结果:
127.0.0.1 localhost
somotherrandomip testing
192.168.0.34 test1ip
192.168.0.35 test2ip
我也读过这个How to check if a string contains a substring in Bash,但我似乎无法理解。
非常感谢任何帮助!
这里有一个 bash
+ awk
解决方案,可以有效地完成这项工作:
#!/bin/bash
array=(
"192.168.0.34 test1ip"
"192.168.0.35 test2ip"
"192.168.0.33 test3ip"
)
awk '
FNR == NR {
aarr[] =
next
}
! ( in aarr)
END {
for (host in aarr)
print aarr[host], host
}
' <(printf '%s\n' "${array[@]}") testing.txt
127.0.0.1 localhost
somotherrandomip testing
192.168.0.33 test3ip
192.168.0.34 test1ip
192.168.0.35 test2ip
备注:
bash
的<( commands )
被称为process-subtitution。它创建一个包含 commands
输出的文件,您可以将其用作参数。
awk
的FNR == NR
是选择第一个文件参数的条件。在这个块中,我创建了一个关联数组,将主机名转换为其新的 IP 地址。
! ( in aarr)
表示打印翻译数组中hostname为not的记录。
END
用于打印翻译数组(主机名的新 IP)。
以下内容适用于我的机器。我将数组更改为关联数组,删除了 grep 的 -x 选项,并使用 sed
就地编辑文件。
#!/bin/bash
#associative array
declare -A array=(
[test1ip]="192.168.0.34"
[test2ip]="192.168.0.35"
)
#Loop over keys of the array
#See parameter expansion in bash manpage
for i in "${!array[@]}"; do
if ! grep -Fq "$i" testing.txt
then
echo "ip-name=$i is not present, so adding it in testing.txt file"
echo "${array[$i]} $i" >> testing.txt
else
echo "ip-name=$i is present in file so running sed"
#Escape sed left hand side
#Adapted for extended regular expressions from https://unix.stackexchange.com/a/129063/309759
i=$(printf '%s\n' "$i" | sed 's:[][\/.^$*+?(){}|]:\&:g')
#Excape right hand side
ipaddr=$(printf '%s\n' "${array[$i]}" | sed 's:[\/&]:\&:g;$!s/$/\/')
#Replace old IP vith new IP
sed -Ei "s/[0-9]+(\.[0-9]+){3} +$i/$ipaddr $i/" testing.txt
fi
done
我正在尝试执行以下操作:
我有一个名为 testing.txt 的文件,每次 IP 地址或地址根据名称(test1ip、test2ip)更改时我都想更新它:
127.0.0.1 localhost
somotherrandomip testing
192.168.0.36 test1ip
192.168.0.37 test2ip
这是我试过的。
#!/bin/bash
array=(
"192.168.0.34 test1ip"
"192.168.0.35 test2ip"
)
for i in "${array[@]}"; do
if ! grep -Fxq "$i" testing.txt
then
echo "ip-name=$i is not present, so adding it in testing.txt file"
echo "$i" >> testing.txt
else
echo "ip-name=$i is present in file, so nothing to do"
fi
done
但是,如果找不到该行,此脚本会附加一个全新的行。我想要实现的是,如果找到 test1ip 或 test2ip 但 ip 地址发生变化,则覆盖该行。
预期结果:
127.0.0.1 localhost
somotherrandomip testing
192.168.0.34 test1ip
192.168.0.35 test2ip
我也读过这个How to check if a string contains a substring in Bash,但我似乎无法理解。
非常感谢任何帮助!
这里有一个 bash
+ awk
解决方案,可以有效地完成这项工作:
#!/bin/bash
array=(
"192.168.0.34 test1ip"
"192.168.0.35 test2ip"
"192.168.0.33 test3ip"
)
awk '
FNR == NR {
aarr[] =
next
}
! ( in aarr)
END {
for (host in aarr)
print aarr[host], host
}
' <(printf '%s\n' "${array[@]}") testing.txt
127.0.0.1 localhost
somotherrandomip testing
192.168.0.33 test3ip
192.168.0.34 test1ip
192.168.0.35 test2ip
备注:
bash
的<( commands )
被称为process-subtitution。它创建一个包含commands
输出的文件,您可以将其用作参数。awk
的FNR == NR
是选择第一个文件参数的条件。在这个块中,我创建了一个关联数组,将主机名转换为其新的 IP 地址。! ( in aarr)
表示打印翻译数组中hostname为not的记录。END
用于打印翻译数组(主机名的新 IP)。
以下内容适用于我的机器。我将数组更改为关联数组,删除了 grep 的 -x 选项,并使用 sed
就地编辑文件。
#!/bin/bash
#associative array
declare -A array=(
[test1ip]="192.168.0.34"
[test2ip]="192.168.0.35"
)
#Loop over keys of the array
#See parameter expansion in bash manpage
for i in "${!array[@]}"; do
if ! grep -Fq "$i" testing.txt
then
echo "ip-name=$i is not present, so adding it in testing.txt file"
echo "${array[$i]} $i" >> testing.txt
else
echo "ip-name=$i is present in file so running sed"
#Escape sed left hand side
#Adapted for extended regular expressions from https://unix.stackexchange.com/a/129063/309759
i=$(printf '%s\n' "$i" | sed 's:[][\/.^$*+?(){}|]:\&:g')
#Excape right hand side
ipaddr=$(printf '%s\n' "${array[$i]}" | sed 's:[\/&]:\&:g;$!s/$/\/')
#Replace old IP vith new IP
sed -Ei "s/[0-9]+(\.[0-9]+){3} +$i/$ipaddr $i/" testing.txt
fi
done