私はxmllint --shell
大きなXMLファイルで作業しており、このwrite
コマンドを使用してテストに使用するXMLフラグメントを作成しています。作成されたコードスニペットには、元のXMLファイル(宣言、名前空間、およびルートノード)の複数行が必要です。手動で行をコピーせずに、この行をファイルに追加できるようにしたいです。代わりに、私はこの非常に退屈なタスクを自動化する関数を書くことができるようにsedを使って行を追加したいと思います。これを説明するために、ここで私が達成しようとしている仕事の例があります。
ソースXML(source.xml):
<?xml version="1.0" encoding="UTF-8"?>
<foo:root xmlns:foo="TheFooNameSpaceIsImportant">
<foo:Entry>
<foo:SomeNode>Foo1</foo:SomeNode>
<foo:AnotherNode>Bar1</foo:AnotherNode>
</foo:Entry>
<foo:Entry>
<foo:SomeNode>Foo2</foo:SomeNode>
<foo:AnotherNode>Bar2</foo:AnotherNode>
</foo:Entry>
<foo:Entry>
<foo:SomeNode>Foo3</foo:SomeNode>
<foo:AnotherNode>Bar3</foo:AnotherNode>
</foo:Entry>
<!-- tens of thousands of others -->
<foo:Entry>
<foo:SomeNode>Foo20432</foo:SomeNode>
<foo:AnotherNode>Bar20432</foo:AnotherNode>
</foo:Entry>
</foo:root>
保存されたXMLフラグメント(sample.xml):
<foo:Entry>
<foo:SomeNode>Foo</foo:SomeNode>
<foo:AnotherNode>Bar</foo:AnotherNode>
</foo:Entry>
したがって、source.xmlの上部2行と下部行にラップする必要があります。ただし、役割のため、以下は失敗します<
。
$ sed -i 1i"`head -n 2 source.xml`" sample.xml
sed: -e expression #1, char 43: unknown command: `<'
このようなサブコマンドで提供される場合、この文字をエスケープする方法はありますか?
ベストアンサー1
sed
上記のコマンドの\
BSD出力で説明されているように、「i」コマンドの後にはテキストが続く必要があります。sed
しかしそれはただ期待する一つテキスト行。より多くのコンテンツを挿入するには、最初の行の末尾にバックスラッシュを追加する必要があります。
sed "1i\\
$(head -n 2 source.xml | sed 's/$/\\/')
" sample.xml
この(ネストされたsed
呼び出し)は少し面白いです。私が書いたように他の場所で、内部スクリプトファイルを編集するために選択するツールではありませんが、次のようsed
になりますex
。
ex -sc '1,2ya | n! | 0pu | x' source.xml sample.xml
この-s
フラグはex
バッチ処理のために自動モードで開始されます。 -c
実行するコマンドを指定します。
1,2ya
最初のファイルの最初の2行をコピー(つまりコピー)しますsource.xml
。
|
コマンド区切り記号。
n!
現在のファイルの変更を取り消し、次のファイルに移動します。 (この場合は何もしないのでn
大丈夫です。)
0pu
以前にコピーした行を「配置」(つまり貼り付け)して、「0」行の後に配置します(つまり、最初の行の上に貼り付け)。
x
終了し、現在のファイルの変更を保存します。
指定されていない(空でもバックアップファイル拡張子を指定する必要があるsed -i
BSDでは機能しません)、POSIXのコマンドとは異なり、上記のコマンドはまさに次のとおりです。sed
-i
ex
POSIX互換。