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>

<또 다른 접근 방식은 각 문자 뒤에 개행 문자를 삽입하거나 >변경하려는 내용이 자체 줄에 있도록 하는 것입니다. 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와 함께 모든 문자를 사용할 수 있기 때문에 작동하며 s반드시 OR s/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

관련 정보