다음과 같이 파일 이름을 생성한다고 가정해 보겠습니다.
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.gtk3
bash입니다. 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
.