0

次のようなドキュメントの大規模な Web サイトがあります。
<title>DOCTITLE</title>
<h1>Some Title</h1>

Cygwin を使用して、すべてのファイルで DOCTITLE を Some Title に置き換えようとしています。

具体的には<h1>、各ファイルからタグの間にあるテキストを抽出し、リテラル文字列 "DOCTITLE" を抽出したテキストに置き換える必要があります。

機能しないが、私が求めているものの精神を示している1つの考えを次に示します。

find . -name "*html"  
       -exec sed -i 
                's/DOCTITLE/'$(grep "h1" | sed 's/<h1>\(.*\)<\/h1>/\1/')'/'
'{}' /;

当然のことながら、これは失敗します。これは、grep に入力がなく、<h1>.

何か案は?

あなたの時間と専門知識をありがとう!

4

2 に答える 2

0

これはあなたのために働くかもしれません(GNU sed):

find . -name "*html" -exec sed -i '$!N;s/DOCTITLE\([^\n]*\n<h1>\([^<]*\)<\/h1>\)/\2\1/;P;D' {}\;

これには、最初に広範なテストが必要になります。

于 2012-07-11T07:38:47.660 に答える
0

の引数はその構文を処理しない$( … )ため、このアプローチ (を使用) は機能しません。ただし、代わりにできることは、そのちょっとした作業を行うように呼び出すことです。sed-execbash

find . -name '*.html' -exec /bin/bash -c 'sed "s/DOCTITLE/$(sed -n '\''\,<h1>.*</h1>,{s,<h1>\(.*\)</h1>,\1,p;q}'\'' '\''{}'\'')/" "{}"' \;

外側は、コマンドが行うsedことを正確に行います。sed内側の$( … )部分は によって展開され、最初bashの の間のテキストのみが生成されます(最初の一致のみを取得する必要がない場合は、はるかに簡単になります)。 <h1>

具体的には、そのインナーsedはデフォルトでは何も出力しません (the -n)。その後、regex に一致する行について<h1>.*</h1>実行しますs,<h1>\(.*\)</h1>,\1,p;q。つまり、HTML タグを取り除き、結果を出力してから終了します。これqにより、最初の一致のみを出力することが保証されます。

;を使用grepして使用する必要がないように注意してください。または、コマンドを最初の一致に制限するオプションをsed -n使用して、以下のコマンドで同じことを行うこともできます。-mgrep

find . -name '*.html' -exec /bin/bash -c 'sed "s/DOCTITLE/$(grep -m1 '\''<h1>.*</h1>'\'' '\''{}'\'' | sed '\''s,<h1>\(.*\)</h1>,\1,'\'')/" "{}"' \;

どちらの場合も、やや恐ろしい引用が行われています。'\''シーケンスは、単一引用符で囲まれた文字列に単一引用符を挿入することです。sedタイトルのスペースが問題を引き起こさないようにステートメントを引用する必要があり、ファイル名のスペースを処理できるようにファイル名を引用する必要があります。

于 2012-07-11T13:05:53.523 に答える