백틱 확장을 사용하여 인수 목록을 채우는 방법은 무엇입니까?


11

도움에서 :help backtick-expansion:

On Unix and a few other systems you can also use backticks for the file name
argument, for example:
    :next `find . -name ver\\*.c -print`
    :view `ls -t *.patch  \| head -n1`
The backslashes before the star are required to prevent the shell from
expanding "ver*.c" prior to execution of the find program.  The backslash
before the shell pipe symbol "|" prevents Vim from parsing it as command
termination.

도움말에서 가져온 명령을 입력하면 오류가 발생합니다.

:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards  

도움말의 예제가 왜 하나 대신 두 개의 백 슬래시를 사용합니까? 왜 작동하지 않습니까?

다음과 같은 일 :

  • find프로그램 전에 쉘에 의해 별이 확장되는 것을 방지하는 두 개의 백 슬래시 중 하나를 제거하면 :

    :next `find . -name ver\*.c -print`
    
  • 백 슬래시를 모두 제거하고 패턴 주위에 작은 따옴표를 넣으면 ver*.c:

    :next `find . -name 'ver*.c' -print`
    

이 시점까지 규칙은 다음과 같습니다.
쉘 명령에 별표가 포함되어 있고 명령 전에 쉘을 확장하지 않으려면 명령 앞에 백 슬래시를 넣거나 패턴 주위에 작은 따옴표를 넣으십시오 .

그러나 도움이 또 다른 예를 제공합니다.

:view `ls -t *.patch  \| head -n1`

이 명령은 수정없이, 작은 따옴표 나 백 슬래시가 필요하지 않습니다.
그것이 작동하는 이유는 ls명령 (명령 -name인수와 달리 find)이 여러 파일 인수를 허용하고 쉘 확장에 문제 가 없기 때문이라고 가정합니다 *.patch.

자,하자 내가 확장자를 가진 모든 파일을 찾아하고 싶은 말은 .conf내부 /etc의 폴더 및 파이프 출력 findgrep문자열을 포함하는 경우에만 일치를 얻을 input.
셸에서 모든 작업 디렉토리에서 다음을 입력합니다.

find /etc -name '*.conf' | grep input

그리고 작동합니다.

vim에서는 역동적 인 명령을 입력하고 파이프 기호 앞에 역 슬래시를 입력하여 vim이 명령 종료로 해석하지 못하도록합니다.

:next `find /etc -name '*.conf' \| grep input`

그리고 작동합니다.

이제 파이프와을 사용하지 않고 동일한 명령을 입력 grep input하면 오류가 발생합니다.

:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards

작은 따옴표로 별을 보호 했는데도이 경우 오류가 발생하는 이유는 무엇입니까?
그리고 왜 지금 오류가 grep input있습니까? 그러나 파이프와 ?

이해를 시도하기 위해 더 간단한 명령을 생각해 냈습니다.

find . -name '*.conf'

.conf작업 디렉토리에서 확장자 가있는 모든 파일을 찾습니다 . 이 명령은 쉘에서 작동합니다.

vim에서 테스트하려면 다음 :next `find . -name '*.conf'`
과 같이 입력하십시오 . 이 경우 점은 vim 세션을 시작한 이후 :pwd내 홈 디렉토리 인 Ex 명령으로 표시되는 현재 작업 디렉토리를 나타 /home/username냅니다.

현재 작업 디렉토리에서 검색을 요청할 때 왜 작동 /etc합니까? 와 같은 임의의 폴더에서 검색을 요청하면 작동하지 않습니까?

이제 vim Ex 명령으로 작업 디렉토리를에서 /home/username로 변경 하고 이전과 동일한 명령을 다시 시도하면 오류가 다시 발생합니다./etc:cd /etc

:next `find . -name '*.conf'`
E79: Cannot expand wildcards

홈 폴더에있을 때 동일한 명령이 작동하는 이유는 무엇 /etc입니까?

나는 어떤 논리가 있다고 확신하지만 그것을 찾을 수는 없습니다.

arglist를 임의의 쉘 명령 (별표, 파이프 포함, 작업 디렉토리에서 디렉토리 검색)으로 채우는 일반적이고 올바른 구문은 무엇입니까?

vim 버전 7.4.942를 사용 하고 있으며 zsh가 기본 쉘입니다. vim -u NORC -Nbash와 zsh에서 최소한의 초기화 ( )로 이러한 명령을 테스트했습니다 .

zsh가 아닌 bash를 호출하도록 vim을 구성해야합니까?


인수로 전달 된 모든 파일로 vim을 시작하려고했는지 궁금합니다. 나는 다음과 같은 것을 의미한다 :vim $(find . -name ver*.c)
Vlad GURDIGA

@VladGURDIGA 난 그냥 시도하고 그들은 쉘에서 예상대로 모든 작업 : vim $(find . -name ver\*.c -print), vim $(ls -t *.patch | head -n1), vim $(find /etc -name '*.conf' | grep input), vim $(find /etc -name '*.conf'),vim $(find . -name '*.conf')
새 기노

@VladGURDIGA 그러나 일반적으로 하나만 있기 때문에 현재 세션을 종료하지 않고 arglist를 채우는 방법을 알고 싶습니다. 나는 또한 파일 그룹을 검색하고 빔 서버로 보내 쉘에서 이동 수 (인수와 --remote: 참조 vi.stackexchange.com/a/5618/4939을 하지만 난 방법을 알고 궁금 해요) 현재 세션에서 직접 수행하십시오. 가능하지 않다면 괜찮지 만 도움말을 읽은 후에는 가능할 것 같습니다. 그렇다면 vim이 왜 비슷한 명령에 다르게 반응하는지 이해하고 싶습니다.
새 기노

첫 번째 샘플 명령에서 닫는 백틱이 누락 된 것처럼 보입니다. ;) 그럼에도 불구하고, 도움말에서 예제는 unix.stackexchange.com/q/104260/23669에 설명 된 것처럼 쉘 확장을 방지하기 위해 하나 대신 두 개의 백 슬래시를 사용 한다고 생각 합니다.
Vlad GURDIGA

find /etc -name '*.conf'작동하지 않는 경우 재미있는 이름이 해당 명령에서 나온 것으로 생각되며 이것이 파이프를 통과했을 때 작동하는 이유 일 수 있습니다 grep.
Vlad GURDIGA

답변:


6

여전히 backtick-expansion을 사용하여 임의의 쉘 명령으로 arglist를 채우는 방법을 모르지만 해결 방법을 찾았습니다.

보낸 사람 :help `=:

You can have the backticks expanded as a Vim expression, instead of as an
external command, by putting an equal sign right after the first backtick,
e.g.:
    :e `=tempname()`
The expression can contain just about anything, thus this can also be used to
avoid the special meaning of '"', '|', '%' and '#'.  However, 'wildignore'
does apply like to other wildcards.

따라서 다음과 같은 쉘 명령을 직접 확장하는 대신 :

:args `shell command`

쉘 명령을 Vim 함수로 보내고 systemlist()표현식 레지스터 =를 사용하여 다음과 같이 결과 표현식을 확장 할 수 있습니다.

:args `=systemlist("shell command")`

일부 키 스트로크를 저장하기 위해 vimrc에 다음과 같은 Ex 명령을 정의했습니다 ( :PAPopulate Arglist).

command! -nargs=1 PA args `=systemlist(<q-args>)`

그리고 다양한 쉘 명령으로 테스트했습니다.

:PA find . -name ver\*.c -print 2>/dev/null
:PA find . -name 'ver*.c' -print 2>/dev/null
:PA ls -t *.patch  | head -n1
:PA find /etc -name '*.conf' 2>/dev/null | grep input
:PA find /etc -name '*.conf' 2>/dev/null
:PA find . -name '*.conf' 2>/dev/null

지금까지는 예상대로 작동하며 명령은 셸에서와 같이 입력 할 수 있습니다 (예 : 파이프를 벗어날 필요가 없음).
직접 백틱 확장보다 더 일관되고 신뢰할 수있는 것 같습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.