AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

    • 主页
    • 系统&网络
    • Ubuntu
    • Unix
    • DBA
    • Computer
    • Coding
    • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 768628
Accepted
mbigras
mbigras
Asked: 2024-02-06 14:22:21 +0800 CST2024-02-06 14:22:21 +0800 CST 2024-02-06 14:22:21 +0800 CST

使用 ed(1) 在 HTML 标签内进行编辑

  • 772

考虑一下我的简陋hello.html文件,它是用强大的编辑器编辑的:

$ ed hello.html 
28
,p
<title>Hello world!</title>

在标题HTML 标签内进行编辑的一般方法是什么(如果您可以在任何 HTML 标签内进行编辑,那就更好了)?

我尝试了在标签内匹配的正则表达式:

s/>.*/>My new title/p
<title>My new title
u
.
<title>Hello world!</title>

</title>但是,可悲的是,您可以看到我砍掉了我的标签(每次都输入该位的工作量太大了!)。

为了进一步学习,我浏览了 Pascal 中的软件工具页面到 174 — 请参阅https://archive.org/details/softwaretoolsinp00kern/page/174/mode/1up?view=theater页面 — 并发现了&有助于到达句子中间:

s/world/& again/p
<title>Hello world again!</title>

但是,这不太正确,因为我想替换中间,而不仅仅是到达中间。

regular-expression
  • 3 3 个回答
  • 58 Views

3 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2024-02-06T15:35:07+08:002024-02-06T15:35:07+08:00

    您可以使用[^<]代替来.匹配除代替之外的任何字符<。

    28
    ed> ,n
    1       <title>Hello world!</title>
    ed> s/>[^<]*/>new title/
    ed> ,n
    1       <title>new title</title>
    

    <另一种方法可能是在每个或之后插入换行符,>以便您想要更改的内容在其自己的行上,您可以c使用以下命令进行更改c:

    28
    ed> ,n
    1       <title>Hello world!</title>
    ed> s/[<>]/\
    &\
    /g
    ed> ,n
    1
    2       <
    3       title
    4       >
    5       Hello world!
    6       <
    7       /title
    8       >
    9
    ed> 5c
    new title
    .
    ed> ,n
    1
    2       <
    3       title
    4       >
    5       new title
    6       <
    7       /title
    8       >
    9
    ed> 1,9j
    ed> ,n
    1       <title>new title</title>
    
    • 2
  2. Chris Davies
    2024-02-06T18:41:50+08:002024-02-06T18:41:50+08:00

    更好的方法是使用 HTML 感知解析器并使用它来编辑内容。我更喜欢的工具是xmlstarlet因为虽然它是一个 XML 解析器/编辑器,但它也可以处理 HTML:

    创建示例页面

    cat >my.html <<'EOF'
    <html>
    <title>Hello world!</title>
    <body><p>Thank you for reading my page</p></body>
    </html>
    EOF
    

    Hello world!用。。。来代替Hello everyone!:

    xmlstarlet format --html my.html 2>/dev/null |
        xmlstarlet edit --omit-decl --update '//title' --value 'Hello everyone!'
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
    <html>
      <head>
        <title>Hello everyone!</title>
      </head>
      <body>
        <p>Thank you for reading my page</p>
      </body>
    </html>
    

    输出写入stdout,这里通常的方法是将其写入临时文件,然后替换原始文件。这并不完美,但可能是可以接受的:

    file=my.html
    (
        [ "${file#/}" = "$file" ] && file="./$file"
    
        xmlstarlet format --html "$file" 2>/dev/null |
            xmlstarlet edit --omit-decl --update '//title' --value 'Hello everyone!' >"$file.tmp" &&
            cp -p -- "$file" "$file.old" &&
            mv -f -- "$file.tmp" "$file"
    )
    

    请注意,如果以以下方式$file开头,-您将收到错误xmlstarlet,并且您无法使用--它将其与真实选项分开。我们在这里所做的是检查文件名是否是绝对的,如果不是,则在前面添加./. cp如果不需要保存原始内容的副本,可以省略该行。

    • 2
  3. Mark McKinstry
    2024-02-06T14:38:51+08:002024-02-06T14:38:51+08:00

    您不应该使用正则表达式来解析 HTML。请参阅https://stackoverflow.com/questions/1732348/regex-match-open-tags- except-xhtml-self-contained-tags

    如果您想使用ed下面的代码来执行此操作,请为您提供的 HTML 标记执行此操作。但使用可能会更好sed。这是有效的,因为您可以将任何字符与 一起使用s,不必是s/old/new/它可以是s|old|new|or s!old!new!。

    $ ed hello.html
    28
    ,p
    <title>Hello world!</title>
    s|<title>.*</title>|<title>foo</title>|
    ,p
    <title>foo</title>
    

    / 字符可以统一替换为任何给定 s 命令中的任何其他单个字符。仅当 / 字符(或替代它的任何其他字符)前面有 \ 字符时,它才可以出现在正则表达式或替换中。

    来自https://www.gnu.org/software/sed/manual/html_node/The-_0022s_0022-Command.html

    • 1

相关问题

  • 如何在匹配后删除几个字符?

  • 使用 POSIX 工具正确处理带有 BOM 的 Unicode 文件

  • 为什么正则表达式与 sed 命令的输入不匹配 [重复]

  • 使用特殊字符转换密码以与期望脚本一起使用

  • 更少:使用 AND 的多个过滤条件

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助
subwaysurfers
my femboy roommate

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve