ファイル内のフィールドを識別する必要があります。フィールドが見つかったら、新しい行を追加してテキストを追加する必要があります。しかし、見つかった単語の前のスペースの数を計算して、そのスペースの数に追加のスペースを2つ追加した後に新しい行を追加できるようにしたいと思います。例えば
入力ファイル:
<tt:abcdef>
.
.
.
</tt:abcdef>
上記の入力ファイルには以前に2つのスペースがあり、<tt:abcdef>
このスペースを計算してから、次のように新しい行を作成したいと思います。
期待される出力ファイル:
<tt:abcdef>
<tt:newvar>
.
.
.
</tt:abcdef>
答え1
入力が示されているように単純で規則的で、xmlstarletなどをインストールできない場合、またはインストールできない場合は、すべてのUnixシステムのすべてのシェルでawkを使用できます。
$ awk '{print} sub(/<tt:abcdef>/," "){print $0 "<tt:newvar>"}' file
<tt:abcdef>
<tt:newvar>
.
.
.
</tt:abcdef>
上記のコードは、空白を計算せずに一致する行にある先行スペースを再利用します。これは強力ではなく、提供された入力を提供された出力に変更することです。さらに必要な場合は、質問を編集して、より代表的な入力/出力の例と要件のより良い説明を提供してください。
答え2
使用幸せ(以前のPerl_6)
raku -pe 's/^ (\s+) \<tt\:abcdef\> /{$/}\n$0 <tt:newvar>/;'
または
raku -pe 's[^ (\s+) \<tt\:abcdef\> ]="{$/}\n$0 <tt:newvar>";'
入力例:
<tt:abcdef>
.
.
.
</tt:abcdef>
出力例:
<tt:abcdef>
<tt:newvar>
.
.
.
</tt:abcdef>
上記は、Perlシリーズのプログラミング言語であるRakuで書かれた答えです。つまり、-pe
自動印刷された1行のフラグは、従来のs///
代替イディオム(2番目の例では.で書かれています)を実装するために使用されますs[…]="…"
。
^ (\s+) \<tt\:abcdef\>
出力で認識順序を正確に再現する必要があるため、一致する変数は演算子(代替)の右半分$/
に含まれます。s///
スペースの数が(\s+)
キャプチャされ、$0
代替アイテムに再度追加されます。上記の解決策はつまり、コードブロック内に表示されますが、$/
実際に{$/}
は(あなたの要求に応じて)中括弧は必要ありません。
上記の方法が最も簡単な解決策です。実際には、複雑なテキストファイルで一致しないタグを見ることができるので、タグペアの検出を実際に考慮することもできます(より複雑なソリューションが必要です)。