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입니다. Fedora에도 vim동일한 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.

관련 정보