我在/var/tmp/
下跟随.xml
个随机文件,我的行只包含:cidr=x.x.x.x/32
或x.x.x.x
,现在我需要搜索IP并替换他们喜欢添加/编辑/ del。
的之前: 的
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
OR
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
但似乎没有像预期的输出一样工作。
答案 0 :(得分:3)
您不需要六个管道和各种命令,只需使用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
您可能想尝试使用我上面使用的示例输入来考虑您正在考虑的任何其他解决方案。
答案 1 :(得分:2)
此行适用于您的示例:
grep...|awk '{gsub(/192.168.1.12[^,"]*[,"]/,"");sub(/cidr=">/,">")}7'
小测试:
kent$ cat f
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">
kent$ awk '{gsub(/192.168.1.12[^,"]*[,"]/,"");sub(/cidr=">/,">")}7' f
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" >
答案 2 :(得分:1)
因为你标记了Perl
ls *xml | xargs script.pl
脚本:
#!/usr/bin/perl
use strict;
use warnings;
my $ip = '192.168.1.12' ;
foreach my $file (@ARGV)
{
open(FILE,$file);
while(<FILE>)
{
s/(cidr="$ip\/32"|cidr="$ip"|$ip,)//;
print "$file: $_";
}
close(FILE);
}