这个逻辑怎么用 bash 实现
- 0次
- 2021-07-18 21:36:15
- idczone
我的需求是 有2个文件,求 1.txt和ip.txt不同的内容。
ip.txt文件内容是
192.168.0.1
192.168.0.2
....
....
192.168.0.255
就是1-255的IP
而1.txt 是随机的一些ip是我在交换机ARP表里面获取到的
192.168.0.9
192.168.0.11
192.168.0.14
192.168.0.126
192.168.0.18
等差不多有50个吧
现在我要整理哪些IP没在用。就写了一个bash脚本来处理
但是运行这个脚本没报错。但是ip.txt的内容变空了,按照我的逻辑思路,ip.txt已经是把1.txt的相同内容过滤掉了。
#!/usr/bin/env bash
for ip in $(cat 1.txt)
do
grep -v "$ip" ip.txt > ip.txt
done
grep ... ip.txt | sponge ip.txt
上面 wwwjfy 才是对的……不要胡乱猜测工具在输出内容前会不会为你缓存整个文本的内容,因为工具为了资源消耗的考虑可能不会如你所愿。
包错 ./ip.sh: line 4: sponge: command not found 是不是sponge是一个单独的工具,要安装的?
明显是的。要省事的话直接弄一个临时文件更快。
你的代码乍一看没错,其实是你在同一管道中读写同一文件,这里是问题。所以你可以改为
grep -v "$ip" ip.txt > iptmp.txt
mv iptmp.txt ip.txt
试试
sort 完 diff 不就行了?
sort 1.txt > using.txt
sort ip.txt > all.txt
comm -13 1.txt ip.txt > unused.txt
错了,最后一行应该是
comm -13 using.txt all.txt > unused.txt
grep -E -v "($(echo -n $(< 1.txt) | tr '[[:blank:]]*' '|'))" ip.txt
谢谢了,同一管道中读写同一文件 。是我这个问题困扰我很久,为什么想不通,他grep输出来的内容然后再重定向到他本身文件会清空,如果是>>他会添加但是> 他直接清空。
comm 这个命令很少用。我去了解他下的功能。
谢谢你的回答 ,你正则表达式用的很熟练。但是我不明白里面的含义。
非得先排序然后再来comm吗?
我实验了一下,但是我发行他最后重新输出了内容就不是排好序的,是打乱了顺序。
cat 1.txt ip.txt ip.txt | sort | uniq -u
其实这种方法也可以吧
bash
for ip in $(cat 1.txt)
do
grep -v "$ip" ip.txt | tee ip.txt
done
我要纠正下我刚才实验了一下 grep -v "$ip" ip.txt | tee ip.txt
这个方法不行,因为我对比了 1.txt和ip.txt文件 最后输出的结果不一样,他多处理很多IP 。结果不正确。
嗯 我怎么没想到 uniq呢? 这算是最简单的了。
http://stackoverflow.com/questions/4780203/deleting-lines-from-one-file-which-are-in-another-file
这个链接有一些讨论还有一个简单的性能比较
grep -v -x -f 1.txt ip.txt 用这种方法貌似会多一些结果,不清楚为什么
我发现 他跟 grep -v "$ip" ip.txt | tee ip.txt 输出的结果不正确,会多删掉 1.txt里面没有的内容。
这种方法输出的结果也是不正确。
@webjin
cat ip.txt
192.168.0.1
192.168.0.10
192.168.0.100
比如:grep -v 192.168.0.10 ip.txt|tee ip.txt
会把192.168.0.100也删除
大哥你多了个 ip.txt ,哎,我怎么没想到 先拼接文件,然后排序 然后去重复。
最简洁的答案应该是 :grep -vf 1.txt ip.txt
> 如果目标文件存在则直接清空
>> 追加到文件末尾
在 for 循环里用 > 每 grep 一次就清空一次 ip.txt ,当然没结果了
不多, 你试一下就知道了.. 你是想要得到这样的结果:只在1.txt里出现过但没在ip.txt里出现
grep -vF ip.txt 1.txt
不是,我的意思是说 我知道某个段的一些IP在使用,然后统计出来,计算哪些IP没使用。
你视乎没理解我的意思。 比如 192.168.0.1-255 这是一个段IP
然后你们你们公司交换机里面 获取到了哪些IP在使用,然后你再去统计哪些IP没使用。
两个文件
楼主用if $?判断一下grep的返回,就知道这个ip在没在用了,然后单独输出到一个文件里
awk -F"." '{a[$4]="1"} END{for(i=1;i<=255;i++){if(a[i]!="1"){print "not used:192.168.0." i} else {print "used:192.168.0." i}} }' 1.txt
不需要ip.txt
grep -v "$ip" ip.txt > ip.txt 你这个txt变空的原因是,重定向,会把ip.txt清空,才执行grep
其实可以不依赖ip.txt:
seq -f "192.168.0.%g" 255 | grep -vf 1.txt - > ip.txt
grep -vwF -f 1.txt ip.txt
这个方法不行,我试了下,结果会不正确的
这有很难么,用不着顺序的ip.txt,直接seq生成间隙数组:
1.txt如下:
192.168.0.9
192.168.0.11
192.168.0.14
192.168.0.126
192.168.0.18
命令执行:
(for U in $(awk '{split($0,a,".");print a[4]}' 1.txt|sort -n) 255; do seq $BEG $((U-1)) | sed 's/^/192.168.0./'; BEG=$((U+1)); done) > r.txt
结果:
$ wc -l 1.txt r.txt
5 1.txt
249 r.txt
254 total
有249个可用地址,逻辑无误。
哦,上面我漏掉了手敲的初始变量BEG=1
BEG=1;
(for U in $(awk '{split($0,a,".");print a[4]}' 1.txt|sort -n) 255; do seq $BEG $((U-1)) | sed 's/^/192.168.0./'; BEG=$((U+1)); done) > r.txt
嗯?我也试过了,貌似没问题啊,你的问题出在哪里?