vim:シェルコマンドの出力をどのように挿入しますか?

vim:シェルコマンドの出力をどのように挿入しますか?

新しいlibvirt XMLファイルを編集したいとしましょう。

virsh dumpxml machine1 > machine2.xml

次に、次のようにファイルを開きますvim

vim machine2.xml

その後、UUIDを変更したいと思います。これでこれを行うには、次を使用します。

:r ! uuidgen

ただし、新しいUUIDは現在の行の下に挿入されます。

<uuid>6r123ttz-6t01-356t-1y7h-g7oe196c8u3m</uuid>
e67baf90-751b-4aea-a14b-aca1b881542b

uuidgenコマンド出力を挿入する方法入力する現在行があるので

<uuid></uuid>

(カーソルは間にあります><)、実行すると次のようにuuidgenなります。

<uuid>e67baf90-751b-4aea-a14b-aca1b881542b</uuid>

問題は、:r新しい行を追加せずにvimコマンドを使用できるかどうかです。

答え1

:read前のコマンド;残念ながら、これらは常に動作します完全なライン。最初に分割してから、前と次の行を組み合わせるか、別のコマンドを使用して問題を解決する必要があります。

これ:help i_CTRL-R命令は任意のレジスタ内容を挿入できます。特別なものがあります式レジスタ:help quote=)Vimscript式を実行し、その結果を使用します。ついに、system()関数は外部コマンドを実行し、対応する出力を返します。

したがって、(挿入モードでは)<C-R>=system('uuidgen')<CR>コマンドの出力は現在の位置に挿入されます。残念ながら、出力には改行があり、保存されているため、</uuid>次の行に移動します。これを防ぐために、system('uuidgen')[0:-2]または式で出力substitute(system('uuidgen'), '\n$', '', '')を切り捨てることができます。

繰り返し挿入の場合、歴史を表現する最後の式を呼び出すために使用できます(押す<Up>)。全体のマッピングを定義すると、より快適になります。

答え2

私は少し遊んでいましたが、:rは常に改行文字を入力しているので、正確に何をしません。しかし、望む結果が出なければなりません。

:.!UUID=`uuidgen` ; echo "<uuid>$UUID</uuid>"

現在の行(カーソルではなく)に標準出力を配置します。インテリジェンスは呼び出されるコマンドで実行されます。

答え3

fu! SetBang(v) range
        if a:v == 1
                normal gv
        endif
        let l:t = &shellredir
        let &shellredir = ">%s\ 2>/dev/tty"
        let @" = join(systemlist(input("\"!"))," ")
        let &shellredir = l:t
endf
nnoremap "! :cal SetBang(0)<cr>
xnoremap "! :cal SetBang(1)<cr>

このボタンを押すたびに、"!ユーザーにコマンドを入力するように求められ、「名前なし」の"レジスタが入力されます。その後、通常どおりにP通常モードまたは視覚モード、Ctrl-R"挿入モードなどで挿入できます。

たとえば、テキストがあります(キャレットはでマークされています|)。

<uuid>|</uuid>

キーを押すと、"!uuidgen<Enter>Pキャレットに新しいUUIDが挿入されます。

もちろん、他のバインディングを代わりに使用することもできます"!

答え4

を使用せずにXMLを直接編集することもできますvim

たとえば、<uuid></uuid>ファイルの一部として提供されている場合は、値を挿入または更新できます。

echo '<uuid></uuid>' |
    xmlstarlet edit --update '//uuid' -v "$(uuidgen)"

出力

<?xml version="1.0"?>
<uuid>79cc09da-a256-46d5-9974-9073cf9d7a9a</uuid>

これにより、仮想マシン定義をテンプレート化し、プログラムでカスタマイズできます。

関連情報