gpt4 book ai didi

linux - BASH - 我如何从整个目录中搜索一个值并找到一些匹配的值,然后通过保存它来即时替换该行

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:23:58 25 4
gpt4 key购买 nike

我在 /var/tmp/ 下有以下随机 .xml 文件,我有这样的行包含:cidr=x.x.x.x/32或仅限 x.x.x.x,现在我需要搜索 IP 并像添加/编辑/删除一样替换它们。

之前:

file1.xml: <user id="1" cidr="192.168.1.12">
file2.xml: <user id="2" cidr="192.168.1.12,192.168.1.13">
file3.xml: <user id="3" cidr="8.8.8.8">
file4.xml: <user id="4" cidr="8.8.8.8/32">
fileX.xml: <user id="5" cidr="192.168.1.12/32">

之后(预期输出):

file1.xml: <user id="1" >
file2.xml: <user id="2" cidr="192.168.1.13">
file3.xml: <user id="3" cidr="8.8.8.8">
file4.xml: <user id="4" cidr="8.8.8.8/32">
fileX.xml: <user id="5" >

现在,要找到哪一行包含匹​​配的 ip 然后替换它,我在一行中尝试类似的东西:

grep -R 'cidr=' ./*.xml              # search in whole directory
| awk '/192.168.1.12/ {print $1}' # find for a given search criteria
| sed 's/^.\///g' # replace some not necessary values
| sed 's/://' # ..
| xargs sed -i s/""/""/ /var/tmp/ # on the fly workout on that line
# + save it to that file

grep -R 'cidr=' ./*.xml              # search in whole directory
| awk '/192.168.1.12/ {print $1}' # find for a given search criteria
| sed 's/^.\///g' # replace some not necessary values
| sed 's/://' # ..
| ( grep -R 'cidr=' ./*.xml
| awk '/192.168.1.12/ {print $4}'
| sed 's/ //g'
)
| xargs sed -i s/""/""/ /var/tmp/ # on the fly workout on that line
# + save it to that file

但似乎没有像预期的输出那样工作。

最佳答案

您不需要半打管道和各种命令,只需使用 find 查找文件并使用 awk 修改它们,例如:

find /var/tmp/ -type f -name '*.xml' -print |
while IFS= read -r file
do
awk '
<whatever>
' "$file" > tmp$$ && mv tmp$$ "$file"
done

下面是编写 awk 脚本的方法:

$ cat file
file1.xml: <user id="1" cidr="192.168.1.12">
file1.xml: <user id="1" cidr="192.168.1012">
file1.xml: <user id="1" cidr="192.168.1.123">
file2.xml: <user id="2" cidr="192.168.1.12,192.168.1.13">
file2.xml: <user id="2" cidr="192.168.1.13,192.168.1.12">
file2.xml: <user id="2" cidr="192.168.1.13,192.168.1.12,8.8.8.8">
file3.xml: <user id="3" cidr="8.8.8.8">
file4.xml: <user id="4" cidr="8.8.8.8/32">
fileX.xml: <user id="5" cidr="192.168.1.12/32">

$ awk -v tgtIp="192.168.1.12" '
BEGIN {
gsub(/\./,"\\.",tgtIp)
tgtIp = tgtIp "(/[[:digit:]]+)?"
tgtIp = "(," tgtIp "\\>)|(\\<" tgtIp ",)|(\\<" tgtIp "\\>)"
}
match($0,tgtIp) {
$0 = substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH)
sub(/cidr=""/,"")
}
{ print }
' file
file1.xml: <user id="1" >
file1.xml: <user id="1" cidr="192.168.1012">
file1.xml: <user id="1" cidr="192.168.1.123">
file2.xml: <user id="2" cidr="192.168.1.13">
file2.xml: <user id="2" cidr="192.168.1.13">
file2.xml: <user id="2" cidr="192.168.1.13,8.8.8.8">
file3.xml: <user id="3" cidr="8.8.8.8">
file4.xml: <user id="4" cidr="8.8.8.8/32">
fileX.xml: <user id="5" >

所以整个 shell 脚本将是:

find /var/tmp/ -type f -name '*.xml' -print |
while IFS= read -r file
do
awk -v tgtIp="192.168.1.12" '
BEGIN {
gsub(/\./,"\\.",tgtIp)
tgtIp = tgtIp "(/[[:digit:]]+)?"
tgtIp = "(," tgtIp "\\>)|(\\<" tgtIp ",)|(\\<" tgtIp "\\>)"
}
match($0,tgtIp) {
$0 = substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH)
sub(/cidr=""/,"")
}
{ print }
' "$file" > tmp$$ && mv tmp$$ "$file"
done

您可能想尝试使用我在上面使用的示例输入考虑的任何其他解决方案。

关于linux - BASH - 我如何从整个目录中搜索一个值并找到一些匹配的值,然后通过保存它来即时替换该行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19191671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com