这个逻辑怎么用 bash 实现 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
webjin
V2EX    Linux

这个逻辑怎么用 bash 实现

  •  
  •   webjin 2014 年 3 月 7 日 6288 次点击
    这是一个创建于 4327 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我的需求是 有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
    38 条回复    1970-01-01 08:00:00 +08:00
    wwwjfy
        1
    wwwjfy  
       2014 年 3 月 7 日
    grep ... ip.txt | sponge ip.txt
    jakwings
        2
    jakwings  
       2014 年 3 月 7 日
    上面 wwwjfy 才是对的……不要胡乱猜测工具在输出内容前会不会为你缓存整个文本的内容,因为工具为了资源消耗的考虑可能不会如你所愿。
    webjin
        3
    webjin  
    OP
       2014 年 3 月 7 日
    @jakwings 包错 ./ip.sh: line 4: sponge: command not found 是不是sponge是一个单独的工具,要安装的?
    jakwings
        4
    jakwings  
       2014 年 3 月 7 日
    @webjin 明显是的。要省事的话直接弄一个临时文件更快。
    7rack
        5
    7rack  
       2014 年 3 月 7 日   1
    你的代码乍一看没错,其实是你在同一管道中读写同一文件,这里是问题。所以你可以改为
    grep -v "$ip" ip.txt > iptmp.txt
    mv iptmp.txt ip.txt
    试试
    Mutoo
        6
    Mutoo  
       2014 年 3 月 7 日
    sort 完 diff 不就行了?
    duzhe0
        7
    duzhe0  
       2014 年 3 月 7 日
    sort 1.txt > using.txt
    sort ip.txt > all.txt
    comm -13 1.txt ip.txt > unused.txt
    duzhe0
        8
    duzhe0  
       2014 年 3 月 7 日
    错了,最后一行应该是
    comm -13 using.txt all.txt > unused.txt
    kfll
        9
    kfll  
       2014 年 3 月 7 日   1
    grep -E -v "($(echo -n $(< 1.txt) | tr '[[:blank:]]*' '|'))" ip.txt
    webjin
        10
    webjin  
    OP
       2014 年 3 月 7 日
    @7rack 谢谢了,同一管道中读写同一文件 。是我这个问题困扰我很久,为什么想不通,他grep输出来的内容然后再重定向到他本身文件会清空,如果是>>他会添加但是> 他直接清空。
    webjin
        11
    webjin  
    OP
       2014 年 3 月 7 日
    @duzhe0 comm 这个命令很少用。我去了解他下的功能。
    webjin
        12
    webjin  
    OP
       2014 年 3 月 7 日
    @kfll 谢谢你的回答 ,你正则表达式用的很熟练。但是我不明白里面的含义。
    webjin
        13
    webjin  
    OP
       2014 年 3 月 7 日
    @duzhe0 非得先排序然后再来comm吗?
    webjin
        14
    webjin  
    OP
       2014 年 3 月 7 日
    @duzhe0 我实验了一下,但是我发行他最后重新输出了内容就不是排好序的,是打乱了顺序。
    winsweet
        15
    winsweet  
       2014 年 3 月 7 日   2
    cat 1.txt ip.txt ip.txt | sort | uniq -u
    webjin
        16
    webjin  
    OP
       2014 年 3 月 7 日
    其实这种方法也可以吧
    #!/usr/bin/env bash
    for ip in $(cat 1.txt)
    do
    grep -v "$ip" ip.txt | tee ip.txt
    done
    webjin
        17
    webjin  
    OP
       2014 年 3 月 7 日
    我要纠正下我刚才实验了一下 grep -v "$ip" ip.txt | tee ip.txt
    这个方法不行,因为我对比了 1.txt和ip.txt文件 最后输出的结果不一样,他多处理很多IP 。结果不正确。
    webjin
        18
    webjin  
    OP
       2014 年 3 月 7 日
    @winsweet 嗯 我怎么没想到 uniq呢? 这算是最简单的了。
    amyangfei
        19
    amyangfei  
       2014 年 3 月 7 日
    http://stackoverflow.com/questions/4780203/deleting-lines-from-one-file-which-are-in-another-file
    这个链接有一些讨论还有一个简单的性能比较
    grep -v -x -f 1.txt ip.txt 用这种方法貌似会多一些结果,不清楚为什么
    webjin
        20
    webjin  
    OP
       2014 年 3 月 7 日   1
    @7rack 我发现 他跟 grep -v "$ip" ip.txt | tee ip.txt 输出的结果不正确,会多删掉 1.txt里面没有的内容。
    webjin
        21
    webjin  
    OP
       2014 年 3 月 7 日
    @kfll 这种方法输出的结果也是不正确。
    amyangfei
        22
    amyangfei  
       2014 年 3 月 7 日
    @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
        23
    webjin  
    OP
       2014 年 3 月 7 日
    @winsweet 大哥你多了个 ip.txt ,哎,我怎么没想到 先拼接文件,然后排序 然后去重复。
    rrfeng
        24
    rrfeng  
       2014 年 3 月 7 日
    最简洁的答案应该是 :grep -vf 1.txt ip.txt

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

    在 for 循环里用 > 每 grep 一次就清空一次 ip.txt ,当然没结果了
    winsweet
        25
    winsweet  
       2014 年 3 月 7 日
    @webjin 不多, 你试一下就知道了.. 你是想要得到这样的结果:只在1.txt里出现过但没在ip.txt里出现
    pfipdaniel
        26
    pfipdaniel  
       2014 年 3 月 7 日
    grep -vF ip.txt 1.txt
    webjin
        27
    webjin  
    OP
       2014 年 3 月 7 日
    @winsweet 不是,我的意思是说 我知道某个段的一些IP在使用,然后统计出来,计算哪些IP没使用。
    webjin
        28
    webjin  
    OP
       2014 年 3 月 7 日
    @pfipdaniel 你视乎没理解我的意思。 比如 192.168.0.1-255 这是一个段IP
    然后你们你们公司交换机里面 获取到了哪些IP在使用,然后你再去统计哪些IP没使用。
    saihuang
        29
    saihuang  
       2014 年 3 月 7 日
    两个文件
    saihuang
        30
    saihuang  
       2014 年 3 月 7 日
    楼主用if $?判断一下grep的返回,就知道这个ip在没在用了,然后单独输出到一个文件里
    vzex
        31
    vzex  
       2014 年 3 月 7 日
    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
        32
    vzex  
       2014 年 3 月 7 日
    grep -v "$ip" ip.txt > ip.txt 你这个txt变空的原因是,重定向,会把ip.txt清空,才执行grep
    nanpuyue
        33
    nanpuyue  
       2014 年 3 月 7 日
    其实可以不依赖ip.txt:
    seq -f "192.168.0.%g" 255 | grep -vf 1.txt - > ip.txt
    pfipdaniel
        34
    pfipdaniel  
       2014 年 3 月 7 日
    @webjin grep -vwF -f 1.txt ip.txt
    webjin
        35
    webjin  
    OP
       2014 年 3 月 7 日
    @nanpuyue 这个方法不行,我试了下,结果会不正确的
    BOYPT
        36
    BOYPT  
       2014 年 3 月 7 日
    这有很难么,用不着顺序的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
        37
    BOYPT  
       2014 年 3 月 7 日
    哦,上面我漏掉了手敲的初始变量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
        38
    nanpuyue  
       2014 年 3 月 8 日
    @webjin 嗯?我也试过了,貌似没问题啊,你的问题出在哪里?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2654 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 11:13 PVG 19:13 LAX 03:13 JFK 06:13
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86