ディレクトリ内の複数のxhtmlファイルのイメージパスを置き換える必要があります。ファイルヘッダーの部分は次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<html xml:lang="en-us" lang="en-us" xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:ns="http://www.w3.org/2001/10/synthesis">
<head>
コマンドで試しましたが、sed
成功しませんでした。特定のsedバージョンのためかもしれませんが、わかりません。私は持っていますGNU sed 4.4
original path:
<img src="/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"
I need replace to:
<img src="graphics/line.jpg"
頑張った
sed -i '.bak' 's/\/api\/v2\/epubs\/urn:orm:book:381260143574\/files/graphics/g' '*.xhtml'
それは戻ってくる
sed: -e expression #1, char 1: unknown command: `.'
また試み
sed -i ' ' 's/\/api\/v2\/epubs\/urn:orm:book:381260143574\/files/graphics/g' '*.xhtml'
it return
sed: can't read s/\/api\/v2\/epubs\/urn:orm:book:381260143574\/files/graphics/g: No such file or directory
sed: can't read *.xhtml: No such file or directory
sed
これは適切ですか?
ベストアンサー1
このsed
ユーティリティは通常、XMLまたはXHTMLファイルの編集には適していません。 XMLは構造化された文書形式であり、行中心ではありません。多くの標準のUnixテキスト操作ツールと同様に、このsed
ユーティリティはライン指向であり、追加の努力がなければ、XMLエンティティのエンコードやデコードなどの操作を処理できません。
サンプル文書にはノードが含まれています(/>
末尾に含まれるように変更されています)
<img src="/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg" />
img
ノード内のスペース(スペース、タブ、および改行)はランダムであり、ノードの追加属性または順序がわからないため、ノード属性のパス名に加えて、sed
以下を確認する必要があります。src
、他の場所ではパス名を変更しないでくださいimg
。
コマンドラインXMLパーサーを使用してこれを行う方法は次のとおりです。
xmlstarlet ed \
-u '//img/@src[. = "/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"]' \
-v 'graphics/line.jpg' file.xhtml
我々はxmlstarlet
かなりよく知られているコマンドラインXMLパーサで、src
属性の元の値がある場合、各ノードの各属性値を文字列に置き換えます。img
graphics/line.jpg
/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg
このコマンドは、ジョブの結果を標準出力に書き込みますが、テスト後に対応する(または)オプションを使用して、期待どおりに機能することを確認xmlstarlet
できます。--inplace
-L
タグが正しい無限img
のように見える場合は、まずXHTMLファイルをフィルタリングしてそれを元に戻すことができます。<img src="...">
xmlstarlet fo --recover --html file.xhtml
形にパイプがあると想像することもできます。
xmlstarlet fo --recover --html file.xhtml |
xmlstarlet ed \
-u '//img/@src[. = "/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"]' \
-v 'graphics/line.jpg'
処理するファイルがすべてパターンと一致する場合、./*.xhtml
つまり.xhtml
ファイル名のサフィックスがあり、現在のディレクトリにある場合は、上記のコマンドのいずれかを使用して単純なシェルループを使用してすべてのファイルを処理できます。 。
for name in ./*.xhtml; do
xmlstarlet ed --inplace \
-u '//img/@src[. = "/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg"]' \
-v 'graphics/line.jpg' "$name"
done
これは、バックアップを作成せずにファイルを変更する--inplace
オプションを使用することに注意してください。xmlstarlet
バックアップデータからこのタスクを実行するのが最善です。
ディレクトリ階層(複数のサブディレクトリがあるディレクトリなど)のすべてのXHTMLファイルに対して上記のコマンドを実行するには、を使用できますfind
。
find . -type f -name '*.xhtml' -exec sh -c '
for name do
xmlstarlet ed --inplace \
-u "//img/@src[. = \"/api/v2/epubs/urn:orm:book:381260143574/files/line.jpg\"]" \
-v "graphics/line.jpg" "$name"
done' sh {} +