ed(1) を使用して HTML タグ内で編集

ed(1) を使用して HTML タグ内で編集

私の謙虚さを考える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>

しかし、単に中間に到達するのではなく、中間を交換したいので、これは正しいことではありません。

答え1

[^<]置換を使用して、置換を除くすべての文字を.一致させることができます<

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

<もう1つのアプローチは、各文字の後に改行文字を挿入または>変更したいものが独自の行になるようにすることです。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

より良いアプローチは、HTML対応パーサーを使用してコンテンツを編集することです。私が好むツールはxmlstarletXMLパーサー/エディタですが、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>

出力が記録されます標準出力ここで一般的なアプローチは、それを一時ファイルに書き込んでから元のファイルを置き換えることです。完璧ではありませんが、おそらく許可されます。

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

答え3

HTMLを解析するために正規表現を使用しないでください。バラよりhttps://stackoverflow.com/questions/1732348/regex-match-open-tags-book-xhtml-self-contained-tags

ed以下のコードを使用してこれを行うには、提供したHTMLタグを使用してください。しかし、使用する方が良いかもしれませんsed。これはANDと一緒にすべての文字を使用できるために機能し、必ずしもsORs/old/new/にはなりません。s|old|new|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

関連情報