• 请不要在回答技术问题时复制粘贴 AI 生成的内容
css3
V2EX  ›  程序员

shell 如何提取文件中的指定内容

  •  
  •   css3 · Apr 2, 2019 · 6130 views
    This topic created in 2611 days ago, the information mentioned may be changed or developed.

    我有这一样一个文件,有个需求,提取指定内容,如,想提取 red 这一组的 ip 出来,应该怎么用 shell 实现啊 :

    // hosts.txt
    [green]
    192.168.1.1
    
    [bule]
    192.168.1.123
    192.168.1.156
    
    [red]
    192.168.1.14
    192.168.1.231
    192.168.14.27
    
    [yellow]
    192.168.2.55
    192.168.13.23
    
    .....
    // 多组这样的内容
    
    
    Supplement 1  ·  Apr 2, 2019
    每组的 ip 数量未知,不固定的
    Supplement 2  ·  Apr 2, 2019
    各组的相对位置也未知,不固定
    25 replies    2019-04-03 13:48:23 +08:00
    CallMeReznov
        1
    CallMeReznov  
       Apr 2, 2019
    j0hnj
        2
    j0hnj  
       Apr 2, 2019
    python3 -c "import configparser; config = configparser.ConfigParser(); config.read('hosts.txt'); print(config['red'])"
    jasonyang9
        3
    jasonyang9  
       Apr 2, 2019
    搜索关键字:linux ini style config parser
    css3
        4
    css3  
    OP
       Apr 2, 2019
    @j0hnj 执行后是这样啊,不是 ip
    <Section: red>😭
    pudgedoor
        5
    pudgedoor  
       Apr 2, 2019 via Android
    Awk 了解一下
    OscarUsingChen
        6
    OscarUsingChen  
       Apr 2, 2019
    shell? 那意思不能用 awk,不能用 grep,不能用 python?
    css3
        7
    css3  
    OP
       Apr 2, 2019 via iPhone
    @OscarUsingChen 可以啊
    taolu
        8
    taolu  
       Apr 2, 2019
    sed -n '/red/,/yellow/p' | sed -e 's/\[red\]//' -e 's/\[yellow\]//' -e '/^$/d'
    d0m2o08
        9
    d0m2o08  
       Apr 2, 2019
    [root@rac1 tmp]# cat 123
    [green]
    192.168.1.1

    [bule]
    192.168.1.123
    192.168.1.156

    [red]
    192.168.1.14
    192.168.1.231
    192.168.14.27

    [yellow]
    192.168.2.55
    192.168.13.23
    [root@rac1 tmp]# sed -n '/\[red\]/,/^$/p' 123
    [red]
    192.168.1.14
    192.168.1.231
    192.168.14.27

    [root@rac1 tmp]#
    taolu
        10
    taolu  
       Apr 2, 2019
    sed -n '/red/,/^$/p' | sed -e 's/\[red\]//' -e '/^$/d'
    修改了下
    OscarUsingChen
        12
    OscarUsingChen  
       Apr 2, 2019
    ^纯 bash,基本没有依赖。
    taolu
        13
    taolu  
       Apr 2, 2019
    @d0m2o08 #9 正好想到,没想到已经发了,哈哈😄
    d0m2o08
        14
    d0m2o08  
       Apr 2, 2019
    @taolu 666
    DiamondbacK
        15
    DiamondbacK  
       Apr 2, 2019
    不知道哪个是你想要的:

    sed -n '/^\[red\]$/,/^ *$/p' # 假定每组有空行分隔
    sed -n '/^\[red\]$/,/^ *$/{/^[^[]/p}'
    sed -n '/^\[red\]$/{:a;/^ *$/!{n;p;ba;}}'
    aver4vex
        16
    aver4vex  
       Apr 2, 2019
    按行读数据。碰到 [red] 之后就提取下方数据,直到碰到[开头的为止。没啥难度。
    sunnyadamm
        17
    sunnyadamm  
       Apr 2, 2019 via Android
    sed,awk 都可以,具体用法自己查
    sunnyadamm
        18
    sunnyadamm  
       Apr 2, 2019 via Android
    再看一下,如果 IP 都是 192.168 开头,你 grep 也可以啊。。。
    lululau
        19
    lululau  
       Apr 2, 2019
    既然 sed / (g)awk 都算 shell,那么这个算吗

    ruby -ne 'print if /^\[red\]$/../^$/'
    liwl
        20
    liwl  
       Apr 2, 2019
    @lululau sed 和 awk 不用装很多社区版都有,ruby 有环境?
    CallMeReznov
        21
    CallMeReznov  
       Apr 2, 2019
    @css3 #4
    楼主,shell 不熟,但是按照
    @j0hnj #2 给的 python 代码实际是可以解决你的问题的
    至于为什么没启用是少了个选项而已.
    代码如下
    https://gist.github.com/CallMeReznov/dd4f93bc36d72da8716a819fa0d4d59d
    我在 WINDOWS 上的 py3 上测试成功了
    ps1aniuge
        22
    ps1aniuge  
       Apr 3, 2019
    win,linux,通用的 powershell 代码,测试通过。

    ```
    $a = Get-Content -LiteralPath 'a:\pscode\TEMP_2019\temp141\aaa.txt' -raw
    [string[]]$b = '[red]'
    $c = '['

    $a.
    split($b,'none')[1].
    split($c)[0] -split "`n"
    ```
    zbinlin
        23
    zbinlin  
       Apr 3, 2019
    awk -v selected=red '
    /^\s*\[.+\]\s*$/ {
    split($0, keys, /\[|\]/);
    curr_key = keys[2];
    next
    }

    selected == curr_key && $0 != "" {
    print $0
    }' hosts.txt
    j0hnj
        24
    j0hnj  
       Apr 3, 2019
    @CallMeReznov #21 看这个输出应该是报错了吧,这个代码我随手写的,没有测试过。楼主的文件并不是合法的 ini 文件,所以并不能用 configparser 去解析。所以我比较好奇为啥楼主运行没报错,而是输出 <Section: red> …
    no1xsyzy
        25
    no1xsyzy  
       Apr 3, 2019
    awk 'BEGIN{K=0} K==1&&/^\d.+/{print $0} /^\[.+\]$/{K=0} /^\[red\]$/{K=1}'
    能够对 [red] 块多次出现的情况应对。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2662 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 74ms · UTC 15:42 · PVG 23:42 · LAX 08:42 · JFK 11:42
    ♥ Do have faith in what you're doing.