这个逻辑怎么用 bash 实现

2014-03-07 10:38:36 +08:00
 webjin
我的需求是 有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
5780 次点击
所在节点    Linux
38 条回复
webjin
2014-03-07 13:04:32 +08:00
@kfll 这种方法输出的结果也是不正确。
amyangfei
2014-03-07 13:05:24 +08:00
@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也删除
webjin
2014-03-07 13:07:50 +08:00
@winsweet 大哥你多了个 ip.txt ,哎,我怎么没想到 先拼接文件,然后排序 然后去重复。
rrfeng
2014-03-07 13:09:54 +08:00
最简洁的答案应该是 :grep -vf 1.txt ip.txt

> 如果目标文件存在则直接清空
>> 追加到文件末尾

在 for 循环里用 > 每 grep 一次就清空一次 ip.txt ,当然没结果了
winsweet
2014-03-07 13:15:16 +08:00
@webjin 不多, 你试一下就知道了.. 你是想要得到这样的结果:只在1.txt里出现过但没在ip.txt里出现
pfipdaniel
2014-03-07 13:36:02 +08:00
grep -vF ip.txt 1.txt
webjin
2014-03-07 14:55:27 +08:00
@winsweet 不是,我的意思是说 我知道某个段的一些IP在使用,然后统计出来,计算哪些IP没使用。
webjin
2014-03-07 14:59:11 +08:00
@pfipdaniel 你视乎没理解我的意思。 比如 192.168.0.1-255 这是一个段IP
然后你们你们公司交换机里面 获取到了哪些IP在使用,然后你再去统计哪些IP没使用。
saihuang
2014-03-07 16:11:25 +08:00
两个文件
saihuang
2014-03-07 16:14:12 +08:00
楼主用if $?判断一下grep的返回,就知道这个ip在没在用了,然后单独输出到一个文件里
vzex
2014-03-07 16:16:02 +08:00
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
vzex
2014-03-07 16:25:35 +08:00
grep -v "$ip" ip.txt > ip.txt 你这个txt变空的原因是,重定向,会把ip.txt清空,才执行grep
nanpuyue
2014-03-07 16:42:57 +08:00
其实可以不依赖ip.txt:
seq -f "192.168.0.%g" 255 | grep -vf 1.txt - > ip.txt
pfipdaniel
2014-03-07 17:25:32 +08:00
@webjin grep -vwF -f 1.txt ip.txt
webjin
2014-03-07 19:02:23 +08:00
@nanpuyue 这个方法不行,我试了下,结果会不正确的
BOYPT
2014-03-07 19:58:45 +08:00
这有很难么,用不着顺序的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个可用地址,逻辑无误。
BOYPT
2014-03-07 20:00:14 +08:00
哦,上面我漏掉了手敲的初始变量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
nanpuyue
2014-03-08 18:07:21 +08:00
@webjin 嗯?我也试过了,貌似没问题啊,你的问题出在哪里?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/103231

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX