首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
brotherlegend
V2EX  ›  Linux

请教个 ilnux shell 的正则提取用 sed 还是 grep ?

  •  
  •   brotherlegend · 2018-02-10 08:58:17 +08:00 · 5161 次点击
    这是一个创建于 708 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学 linux shell 一直学不会 sed 与  grep 的用法,希望大佬指点一下

    打算用来提取 html 里面的内容,测试代码如下

    <tr border=0>
    <tr><td valign=top>
    <div id="leftside">
      <div class="clear">
      </div>
      <div id="playvideo">
        <div id="playvideo-videoname">
                韩式 Sussi
            </div>
        <div id="playvideo-content">
          <div class="arrow-general">
            &nbsp;
          </div>    
            <div class="videoplayer">
                <video id="vid" class="video-js vjs-default-skin vjs-big-play-centered"
            controls preload="auto" width="465" height="360"
             poster="http://img2.aliyun.com/thumb/FA13AS3456XVB.jpg"      >
          <source src="http://v.advideos.com//mp43/FA13AS3456XVB.mp4?st=boGNNUn6--7TxTJJ8uKtjA&e=1518240294" type='video/mp4'>
                </div>
            </div>
        </div>
    </div>
    </div>
    </tr>
    </table>
    

    1、想要提取

    <div id="playvideo-videoname">
                韩式 Sussi
            </div>
    

    里面的 韩式 Sussi

    2、和

    <source src="http://v.advideos.com//mp43/FA13AS3456XVB.mp4?st=boGNNUn6--7TxTJJ8uKtjA&e=1518240294" type='video/mp4'>
    

    里面的 http://v.advideos.com//mp43/FA13AS3456XVB.mp4?st=boGNNUn6--7TxTJJ8uKtjA&e=1518240294 url ,当面页面里面可能有好几个 标签 ,判断唯一的另一个依据就是字串有带 .mp4

    听说 sed 只能按行来提,这样的话第一个要提取的内容老是提不出来。第二个因为是在 src 里面而且通配另一个字串,原谅我正则表达 式真的看不懂。

    请大佬们解惑。

    39 回复  |  直到 2018-02-15 11:58:06 +08:00
    loginv2
        1
    loginv2   2018-02-10 08:59:24 +08:00 via Android
    都不用.用 awk
    loginv2
        2
    loginv2   2018-02-10 09:00:56 +08:00 via Android
    好像也不对,话说回来正常情况下不应该用正则,应该解析 xml
    brotherlegend
        3
    brotherlegend   2018-02-10 09:03:04 +08:00
    @loginv2 那如果 html 格式不规范的话 解析岂不是会失败?
    nightcat
        4
    nightcat   2018-02-10 09:07:57 +08:00
    sed -A1 是加上匹配条目的后一行,sed -B1 是加上前一行,行数可以换,应该能满足你第一条要求。。。
    nightcat
        5
    nightcat   2018-02-10 09:09:51 +08:00
    @nightcat 打错了是 grep 不是 sed
    mingongge
        6
    mingongge   2018-02-10 09:22:52 +08:00
    专注于 linux 系统运维、运维架构、各类高可用技术,热衷于分享开源技术,热爱开源、拥抱开源!!我是 80 后民工哥,微信公众号:民工哥 linux 运维,我为自己代言,谁说 80 后不能活出精彩人生!!!
    关于 命令三剑客的文章可以参考下面的链接
    https://mp.weixin.qq.com/s?__biz=MzI0MDQ4MTM5NQ==&mid=2247484807&idx=1&sn=9fd2359b67d45aa9ea3f23231a19dc1c&chksm=e91b609bde6ce98d000b7e377867c6d45a56eb85343dfd345c8a38f7180f850f0956ff972add#rd
    boboliu
        7
    boboliu   2018-02-10 09:39:46 +08:00
    为啥不直接 beautifulsoup 呢。。。
    iac
        8
    iac   2018-02-10 09:40:14 +08:00
    sed -n '/playvideo-videoname/,+2{/1/n;p}' test.log
    lulinux
        9
    lulinux   2018-02-10 09:51:36 +08:00
    sed 功能稍微强大一点。
    singer
        10
    singer   2018-02-10 10:04:11 +08:00 via iPhone
    awk 正则
    uyhyygyug1234
        11
    uyhyygyug1234   2018-02-10 10:11:44 +08:00
    pyquery bs4 啊!!
    jianguiqubaa
        12
    jianguiqubaa   2018-02-10 10:19:13 +08:00   ♥ 1
    https://github.com/ericchiang/pup


    pup is a command line tool for processing HTML. It reads from stdin, prints to stdout, and allows the user to filter parts of the page using CSS selectors.

    Inspired by jq, pup aims to be a fast and flexible way of exploring HTML from the terminal.


    另外一个思路
    wampyl
        13
    wampyl   2018-02-10 10:22:30 +08:00 via iPhone
    bs4 吧。或者 sed 提取出.mp4 那一行,然后再用 awk 处理
    jianguiqubaa
        14
    jianguiqubaa   2018-02-10 10:26:55 +08:00
    v2er 写的工具 https://github.com/shinima/temme

    这个也挺不错
    lance6716276
        15
    lance6716276   2018-02-10 11:00:15 +08:00 via Android
    HTML 不是正则语言吧…
    wweir
        16
    wweir   2018-02-10 12:00:22 +08:00   ♥ 1
    两条命令

    sed -n -E '/playvideo-videoname/{n;s/^\s*(.*?)\s*$/\1/p}'

    awk -F '"' '/advideos.com/{print $2}'
    wweir
        17
    wweir   2018-02-10 12:02:20 +08:00   ♥ 1
    @wweir 写正则的风格比较严谨,所以看着会有点抽象
    coolxl
        19
    coolxl   2018-02-10 12:03:47 +08:00
    第一个:过滤出关键字 “ playvideo-videoname ”的下一行 grep -A 1 ‘ playvideo-videoname ’ file
    第二个:过滤出关键字“ source src ”的行,再 awk 用 “ 作分隔符,取第二段。grep 'source src' |awk -F '"' '{print $2}' file
    brotherlegend
        20
    brotherlegend   2018-02-10 12:27:12 +08:00 via Android
    @boboliu 如果用 python 就简单啦,就是只想用 shell
    brotherlegend
        21
    brotherlegend   2018-02-10 12:37:59 +08:00 via Android
    @wweir 请收下我的膝盖,完美解决,我研究研究代码的意思
    brotherlegend
        22
    brotherlegend   2018-02-10 12:38:50 +08:00 via Android
    @coolxl 谢谢 等会试试
    liuxu
        23
    liuxu   2018-02-10 13:06:35 +08:00   ♥ 3
    @coolxl
    第二个可以直接
    grep -o "http://.*\.mp4[^\"]*"
    brotherlegend
        24
    brotherlegend   2018-02-10 14:56:18 +08:00
    @liuxu 简单粗暴,牛
    artandlol
        25
    artandlol   2018-02-10 15:20:21 +08:00 via iPhone
    @loginv2 最简单的不是正则,而是 jQuery

    用 sed 则是先匹配到相 cclas 或者 id 然后把尖括号里面的替换位空。

    还有可行的就是 python 写多次正则匹配提取内容
    pkookp8
        26
    pkookp8   2018-02-10 19:14:51 +08:00 via Android
    grep -v \<
    第一题,不知道是不是取巧了
    pkookp8
        27
    pkookp8   2018-02-10 19:18:03 +08:00 via Android
    突然发现楼主标题字母顺序反了...
    abscon
        28
    abscon   2018-02-10 19:50:48 +08:00 via iPhone
    三个问题:
    1. ilnux shell 什么鬼?不存在的。
    2. linux shell 什么鬼?不存在的。
    3. 为什么要用正则来解析 HTML ?用个解析器不好么?
    likuku
        29
    likuku   2018-02-10 23:47:02 +08:00
    少年误入歧途了...
    kualalumpur
        30
    kualalumpur   2018-02-11 00:28:22 +08:00   ♥ 1
    #!/usr/bin/env bash

    # 一个使用 awk 和正则的解决方案

    # HTML 文件变量
    FILE="file.html";

    cat $FILE | # 显示 HTML 文件内容
    awk 'in_range && /<\/div>/ { # 结束标记
    gsub(/^\s+/, "", str); #去掉开头空白
    gsub(/\s+$/, "", str); #去掉尾部空白
    print str;
    exit;
    }
    in_range { # 需要的内容
    str=str $0; # awk 用空格连接字符串
    }
    /playvideo\-videoname/ { # 开始标记
    in_range=1;
    }';

    cat $FILE | # 显示 HTML 文件内容
    awk '/http(.+)\.mp4/ { # 匹配行

    prefix=index($0, "http"); #查找
    url=substr($0, prefix); # 移头

    suffix=index(url, "\""); #查找
    url=substr(url, 1, suffix - 1); # 去尾

    print url; # 显示出来
    }';
    kualalumpur
        31
    kualalumpur   2018-02-11 00:30:12 +08:00   ♥ 1
    feichao
        32
    feichao   2018-02-11 00:56:43 +08:00   ♥ 1
    如果不一定要用正则的话,用 HTML 解析工具会更方便一些

    用 temme 的话这个挺方便的: https://runkit.com/shinima/snippet-for-ilnux-shell
    需要先在命令行用 yarn/npm 安装 temme
    matsuz
        33
    matsuz   2018-02-11 04:11:08 +08:00 via iPhone
    XPath, CSS 选择器了解一下
    brotherlegend
        34
    brotherlegend   2018-02-11 09:02:47 +08:00 via Android
    @abscon 嗯 一根筋 就是只用 shell 不打算用任何第三方
    brotherlegend
        35
    brotherlegend   2018-02-11 09:03:23 +08:00 via Android
    @kualalumpur 这个我看得懂哈哈谢谢
    abscon
        36
    abscon   2018-02-11 09:51:22 +08:00 via iPhone   ♥ 2
    @brotherlegend
    首先,shell 有很多种,你说的具体是哪个 shell。不同的 shell 可能有不同的语法,脚本在某个 shell 能跑,另一个可能就不行;
    其次,shell 又不是专为 Linux 开发的,请不要用「 Linux shell 」这么奇怪的称呼。你学的「 Linux shell 」的经验,相当一部分都能在其他操作系统上用到;
    再次,sed 和 awk 都是独立的程序,在不同的 shell 上都能用,你学的并不是 shell 而是 sed 程序和 awk 程序;
    最后,正则语言相比 html 来说是有点 low 的,不一定能满足要求,想省心省力最好用 html parser。
    brotherlegend
        37
    brotherlegend   2018-02-11 11:16:34 +08:00 via Android
    @abscon 批评的是,不过这样写我的 vps
    都能直接运行就 ok 拉
    brotherlegend
        38
    brotherlegend   2018-02-11 11:17:18 +08:00 via Android
    @feichao 谢谢
    gpw1987
        39
    gpw1987   2018-02-15 11:58:06 +08:00
    sed 取行,awk 取列
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   996 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 27ms · UTC 21:23 · PVG 05:23 · LAX 13:23 · JFK 16:23
    ♥ Do have faith in what you're doing.