vim - 一重引用符と二重引用符が混在するファイル名をエスケープする方法は?

vim - 一重引用符と二重引用符が混在するファイル名をエスケープする方法は?

次のようにファイル名を生成するとします。

xb@dnxb:/tmp/test$ touch '"i'"'"'m noob.mp4"'
xb@dnxb:/tmp/test$ ls -1
"i'm noob.mp4"
xb@dnxb:/tmp/test$ 

次に、vim .Netrw ディレクトリのリストを入力します。

" ============================================================================
" Netrw Directory Listing                                        (netrw v156)
"   /tmp/test
"   Sorted by      name
"   Sort sequence: [\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$
"   Quick Help: <F1>:help  -:go up dir  D:delete  R:rename  s:sort-by  x:special
" ==============================================================================
../
./
"i'm noob.mp4"

次に[ファイルの表示]をクリックしますEnter。タイプ:

:!ls -l %

エラーが表示されます。

xb@dnxb:/tmp/test$ vim .

ls: cannot access '/tmp/test/i'\''m noob.mp4': No such file or directory

shell returned 2

Press ENTER or type command to continue

私も次のことを試しました。

[1] :!ls -l '%':

Press ENTER or type command to continue
/bin/bash: -c: line 0: unexpected EOF while looking for matching `"'
/bin/bash: -c: line 1: syntax error: unexpected end of file

shell returned 1

Press ENTER or type command to continue

[2] :!ls -l "%":

Press ENTER or type command to continue
/bin/bash: -c: line 0: unexpected EOF while looking for matching `''
/bin/bash: -c: line 1: syntax error: unexpected end of file

shell returned 1

Press ENTER or type command to continue

[サム] :!ls -l expand("%"):

/bin/bash: -c: line 0: syntax error near unexpected token `('
/bin/bash: -c: line 0: `ls -l expand(""i'm noob.mp4"")'

shell returned 1

Press ENTER or type command to continue

[4] !ls -l shellescape("%"):

/bin/bash: -c: line 0: syntax error near unexpected token `('
/bin/bash: -c: line 0: `ls -l shellescape("/tmp/test/"i'm noob.mp4"")'

shell returned 1

Press ENTER or type command to continue

[5] !ls -l shellescape(expand("%")):

/bin/bash: -c: line 0: syntax error near unexpected token `('
/bin/bash: -c: line 0: `ls -l shellescape(expand("/tmp/test/"i'm noob.mp4""))'

shell returned 1

Press ENTER or type command to continue

私の究極の目標は+を介してrsync実行することです。たとえば、次のようになります。Ctrlc

nnoremap <C-c> :!eval `ssh-agent -s`; ssh-add; rsync -azvb --no-t % [email protected]:/home/xiaobai/storage/

私のプラットフォームはKali Linuxのvim.gtk3bashです。 Fedoravimにもgvim同じ問題があります。

vimで一重引用符と二重引用符を含むファイル名をエスケープする正しい構文は何ですか?

【書き直す】

exec '!ls -l' shellescape(expand('%'))rsyncうまくいきますが、まだ上記の作業を行う方法がわかりません。このより複雑なコマンドについては、引用符をどこに追加するのかわかりませんrsync

答え1

確立されたワイルドカードの回答ファイル名修飾子を使用すると、必要な:Sものを取得できます。 ()文書によると:h %:S

:S      Escape special characters for use with a shell command (see
        |shellescape()|). Must be the last one. Examples:
            :!dir <cfile>:S
            :call system('chmod +w -- ' . expand('%:S'))

あなたの例を使用して:

$ touch '"I'\''m also a n00b.txt"'
$ ls
"I'm also a n00b.txt"

だからvim '"I'\''m also a n00b.txt"'、チャジャン:

:!ls %:S

"I'm also a n00b.txt"

ファイル名:S修飾子はVim 7.4で利用可能

答え2

から:help filename-modifiers

The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<sfile>",
"<afile>" or "<abuf>".  ...

...
    :s?pat?sub?
            Substitute the first occurrence of "pat" with "sub".  This
            works like the |:s| command.  "pat" is a regular expression.
            Any character can be used for '?', but it must not occur in
            "pat" or "sub".
            After this, the previous modifiers can be used again.  For
            example ":p", to make a full path after the substitution.
    :gs?pat?sub?
            Substitute all occurrences of "path" with "sub".  Otherwise
            this works like ":s".

したがって、二重引用符または一重引用符のみを処理する代わりにバックスラッシュで逃げようすべて以上:

:!ls -l %:gs/[^0-9a-zA-Z_-]/\\&/

指定したテストファイル名と完全に機能します。

必要な絶対パスを使用するには、最後に以下を追加rsyncできます。:p

:!ls -l %:gs/[^0-9a-zA-Z_-]/\\&/:p

実際にすべての文字をバックスラッシュにエスケープすると、うまく機能し、入力するのに時間がかかりません。

:!ls -l %:gs/./\\&/:p

だからあなたのrsync命令に応じて、%使用する代わりに%:gs/./\\&/:p

関連情報