vi 또는 vim을 사용하여 줄 번호로 지정된 여러 줄의 코드 주석 처리


20

이 스택 오버플로 질문 에서 vi/ vim를 사용 하여 지정된 범위의 줄 번호를 주석 처리 할 수 있다는 것을 배웠습니다 . 예를 들어 다음 bash 스크립트가 있다고 가정하십시오.

#!/bin/bash

This
is
my
very
very
great
script

지금은 (단어를 포함하는 8을 통해 줄 번호 6을 주석한다고 가정 very, verygreat사용) #주석 문자를. 에서가 vi/ vim나는 간단하게 입력 할 수 있습니다 :6,8s/^/#다음을 얻을 :

#!/bin/bash

This
is
my
#very
#very
#great
script

이것은 6 행에서 8 행까지 주석 처리됩니다.

내 질문이됩니다 유사 하나 라이너를 입력 할 수있다 제거# 8 (파일에 있지만 다른 주석 처리 된 줄)을 통해 라인 6에서 주석 문자를?

이 말을하는 데, 나는 실제로 사용하고 있는지 여부에 대한 논쟁이 있음을 인식 vi하거나 vim. 실제로 script.sh는 명령 으로 파일 을 엽니 다 vi script.sh. 또한 명령을 입력하면을 which vi얻습니다 /usr/bin/vi. 그럼에도 불구하고 간단히 입력 vi하고을 누르면 Enter다음을 얻습니다.

~                              VIM - Vi IMproved
~
~                               version 7.2.330
~                           by Bram Moolenaar et al.
~                 Vim is open source and freely distributable
~
~                           Sponsor Vim development!
~                type  :help sponsor<Enter>    for information
~
~                type  :q<Enter>               to exit
~                type  :help<Enter>  or  <F1>  for on-line help
~                type  :help version7<Enter>   for version info

실제로 사용하고 있다고 제안하는 것 같습니다 vim. PC에서 SSH를 사용하여 원격 Ubuntu Linux 클러스터에 액세스하고 있습니다. Ubuntu Linux GUI를 사용하지 않습니다.

답변:


22

당신이 사용할 수있는:

:6,8s/^#//

그러나 시각적 선택 차단 모드를 사용하는 것이 훨씬 쉽습니다. 6 행 시작으로 이동하고을 누르고 Ctrl-v8 행으로 이동하여을 누릅니다 x.

도있다 "괴상한 주석 기" 플러그인은.


2
NERD Commenter내 의견으로는 여기로가는 길이야! +1
user1146332

7

내가 사용하여 질문 지정을 알 vi거나 vim수동으로 파일을 열 필요없이이 작업을 수행하는 몇 가지 다른 옵션을하지만, 여기에 있습니다 :

  • perl -ne 'if($. <=8 && $. >= 6){s/^\s*#//;}print' foo.sh 
    
  • 펄 버전> = 5.10

    perl -ne '$. ~~ [6..8] && s/^\s*#//;print' foo.sh 
    

    파일의 내용이 인쇄됩니다. 다른 파일 ( > new_file.sh)로 리디렉션 하거나 i파일을 제자리에서 편집하는 데 사용할 수 있습니다.

    perl -i -ne '$. ~~ [6..8] && s/^\s*#//;print' foo.sh 
    
  • sed

    sed '6,8 s/^ *#//' foo.sh
    

    다시, 원본 파일을 편집하려면 다음을 사용하십시오 i.

    sed -i '6,8 s/^ *#//' foo.sh
    
  • awk/ gawk등 :

    gawk '(NR<=8 && NR>= 6){sub("^ *#","")}{print}' foo.sh
    
  • 순수 bash:

    c=1; while read line; do 
      if [ $c -ge 6 ] && [ $c -le 8 ]; then 
         echo "${line/\#/}"
      else 
         echo $line 
      fi
      let c++; done < foo.sh
    

1
"파일을 수동으로 여는 것"의 문제는 아닙니다. 일반적으로 편집하는 동안 육안 검사시 어떤 줄을 주석으로 표시할지 결정하기 때문입니다.
Paulo Almeida

2
@PauloAlmeida 당신은 물론입니다. OP는 이미 줄 번호를 알고 있기 때문에 유용하다고 생각했습니다 (첫 번째 명령으로 주석을 처리하는 데 사용 되었기 때문에). 어쨌든 내가 보여주는 도구는 다양한 문제에 적용될 수 있습니다.
terdon

4

vivim대부분의 GNU / Linux 배포판에 대한 심볼릭 링크 이므로 실제로 vim입력 할 때 사용하고 있습니다 vi.

주석을 제거하려면 다음을 입력하십시오. :6,8s/^#//또는  기호 :6,8s/^\s*#//앞에 선행 공백을 버리십시오 #.


1
정말 고마워. 오타가있는 것 같습니다. 아마해야 :6,8s/^#//하고 6,8s/^\s*#//?
Andrew

3

을 사용하고있을 것입니다 vim.tiny. 어쨌든 다음을 사용하여 초기 주석을 제거 할 수 있습니다.

:6,8s/^#//

물론 다른 방법으로 (예 : 추가 공간이있는 경우) 삽입하면 다른 것을 제거해야합니다. 전체 vim을 사용하면 시각적으로 열을 선택하고 문자를 삽입 / 삭제하는 것이 동일한 작업을 수행하는 더 쉬운 방법입니다.


3

개인적으로 내가 가장 좋아하는 방법은 비주얼 블록 모드를 사용하는 것입니다

ctrl+ v비주얼 블록 모드의 화살표 키를 입력하거나 선과 눌러 선택 hjkl하는 x이상 del.

그들을 다시 원하십니까?

ctrl+ v선택 후 I(자본 i)#Esc


3

AFAIK, vi는 일반적으로 오늘날 vim의 심볼릭 링크입니다 ( which vi또는 type vi심볼릭 링크를 따르십시오). 아마도 /usr/bin/vi-> /etc/alternatives/vi-> 일 수도 /usr/bin/vim.basic있습니다.

개인적으로 여러 주석 줄을 제거하려면 세로 블록을 선택 CtrlV하고 삭제하는 것이 좋습니다. 당신이 여러 줄에 주석 기호를 추가해야하는 경우, 당신은 수 CtrlV, 다음 ShiftI, 입력 #Esc및 코멘트는 여러 줄에 추가됩니다.


2

위의 답변은

:6,8s/^#//

완벽한 솔루션이지만 입력하기가 다소 번거 롭습니다. 에서 새 명령을 정의하여 단순화 할 수 있습니다 ~/.vimrc.

command -range=% C :<line1>,<line2>s/^/#/
command -range=% D :<line1>,<line2>s/^#//

그리고 당신은 입력 할 수 있습니다

:6,8C
:6,8D

명령을 배치 / 삭제합니다.

시각 모드가 마음에 들면지도를 정의 할 수 있습니다

map <F7> :s/^/#/<CR>
map <F8> :s/^#//<CR>

당신은 단지 시각적 모드, 언론 라인 범위를 선택해야한다는 이러한 F7F8각각 의견을 넣어 제거 할 수 있습니다.


1

에 의해 플러그인을이 생활 변화가있다 tpope라고는vim-commentary

https://github.com/tpope/vim-commentary

이 플러그인은 다음을 제공합니다 .

  • 제정신
  • 제대로 들여 쓰기 된 주석
  • 비어 있거나 불필요한 줄을 주석 처리하지 않습니다

사용법 :

  • Vundle을 통해 설치하십시오 (또는 병원체라고 생각합니다).
  • 텍스트를 눌러 강조 표시 :로 표시됩니다:<,'>
  • 여기에 Commentary :<,'>Commentary를 입력하고 Enter를 누르십시오.
  • 봄. 너의 새싹.

1

이 답변은 1) 시각적 모드에서 1 개의 단축키로 들여 쓰기 수준을 유지하고 2) 설명하기 위해 주석 달기 / 주석 해제를 차단 .vimrc하기 위해 붙여 넣을 올바른 코드를 표시 vim 7.4+합니다.

코드는 다음과 같습니다.

let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.[ch]    let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.cpp    let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.py    let b:commentChar='#'
autocmd BufNewFile,BufReadPost *.*sh    let b:commentChar='#'
function! Docomment ()
  "make comments on all the lines we've grabbed
  execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
endfunction
function! Uncomment ()
  "uncomment on all our lines
  execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
endfunction
function! Comment ()
  "does the first line begin with a comment?
  let l:line=getpos("'<")[1]
  "if there's a match
  if match(getline(l:line), '^\s*'.b:commentChar)>-1
    call Uncomment()
  else
    call Docomment()
  endif
endfunction
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>

작동 방식 :

  • let b:commentChar='//': vim에 변수를 만듭니다. 은 b여기 경우 현재 열려있는 파일을 의미하는 버퍼를 포함하는 범위를 말한다. 주석 문자는 문자열이며 따옴표로 묶어야하며 따옴표는 주석을 토글 할 때 대체되는 문자의 일부가 아닙니다.

  • autocmd BufNewFile,BufReadPost *...: 자동 명령은 여러 가지를 트리거하며,이 경우 새 파일 또는 읽기 파일이 특정 확장자로 끝나면 트리거됩니다. 일단 트리거되면 다음 명령을 실행하여 commentChar파일 유형에 따라 변경할 수 있습니다 . 이 작업을 수행하는 다른 방법이 있지만 초보자와 더 혼동됩니다 (나 같은).

  • function! Docomment():로 시작 function하고 끝나는 함수가 선언됩니다 endfunction. 함수는 대문자로 시작해야합니다. !이 함수로 정의 이전 기능 덮어 보장하지만 Docomment()이 버전을 Docomment(). 이 없으면 !오류가 있었지만 vim 명령 줄을 통해 새 기능을 정의했기 때문일 수 있습니다.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': 실행은 명령을 호출합니다. 이 경우 전체 버퍼 또는 강조 표시된 섹션 substitute과 같은 범위 (기본적으로 현재 줄임)를 취할 수 있는을 실행 합니다. 줄의 시작 부분에 공백이 오는 정규 표현식으로, 뒤에 (으로 인해 ) 추가됩니다 . 때문에 여기가, 문자열 연결에 사용되는 캔은 따옴표로 포장 할 수 없습니다. 인수 앞에이 인수를 일치시키는 문자를 이스케이프 할 수 있습니다 (이 경우 및 ) . 그런 다음 문자열 의 끝과 다시 연결합니다 .%'<,'>^\s*&.escape()escape()commentChar\/\substitutee깃발. 이 플래그를 사용하면 조용히 실패 할 수 있습니다. 즉, 주어진 줄에서 일치하는 항목을 찾지 못하면 소리를 내지 않습니다. 전체적으로이 줄을 사용하면 첫 글자 바로 앞에 공백과 주석 문자를 넣을 수 있습니다. 이는 들여 쓰기 수준을 유지한다는 의미입니다.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': 이것은 우리의 마지막 큰 명령과 비슷합니다. 이 고유 한, 우리는, 우리가 \v우리를 피할 필요가 없도록 ()하고 1, 우리와 함께 만든 그룹을 의미합니다 (). 기본적으로 우리는 공백으로 시작하는 줄과 일치하고 주석 문자 다음에 공백이 따르며 첫 번째 공백 세트 만 유지합니다. 다시 말하지만, e우리는 그 줄에 주석 문자가없는 경우 우리가 자동으로 실패 할 수 있습니다.

  • let l:line=getpos("'<")[1]: 이것은 주석 문자와 마찬가지로 변수를 설정하지만 l로컬 범위 (이 함수의 로컬)를 나타냅니다. getpos()이 경우 강조 표시의 시작 위치와 [1]열 번호와 같은 다른 항목이 아닌 행 번호에만 관심 이 있다는 의미입니다.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: 당신은 어떻게 if작동 하는지 알고 있습니다. match()첫 번째 것이 두 번째 것을 포함하는지 확인하므로 강조 표시를 시작한 줄을 잡고 공백으로 시작하고 주석 문자가 오는지 확인합니다. 일치 match()하는 인덱스가없는 경우 인덱스를 반환합니다 -1. if0이 아닌 모든 숫자를 참으로 평가 하므로 출력이 -1보다 큰지 확인해야합니다. 의 비교는 vim거짓이면 0을, 참이면 1을 반환합니다. 이것이 if올바르게 평가되기를 원합니다.

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremap다음 명령을 시각적 모드로 매핑하지만 재귀 적으로 매핑하지 마십시오 (다른 방법으로 사용할 수있는 다른 명령은 변경하지 않음). 기본적으로, 당신이 독창적 인 초보자라면 항상 noremap물건을 깨지 않도록하십시오. <silent>"나는 당신의 말을 원치 않고 단지 당신의 행동"을 의미하며 명령 행에 아무것도 인쇄하지 말라고 지시합니다. <C-r>우리가 매핑하는 것인데,이 경우에는 ctrl + r입니다 (이 매핑을 사용하여 일반 모드에서 "redo"에 Cr을 정상적으로 사용할 수 있습니다). C-u다소 혼란 스럽지만 기본적으로 시각적 강조 표시를 잃지 않도록합니다 ( 이 답변 에 따르면 명령 '<,'>이 우리가 원하는 것으로 시작하게합니다 ).call여기에서 vim에게 우리가 명명 한 기능을 실행하도록 지시 <cr>하고 enter버튼을 누르는 것을 말합니다 . 실제로 함수를 호출하려면 한 번만 누르십시오 (그렇지 않으면 call function()명령 줄에 방금 입력 한 것입니다. 대체 대체물을 완전히 찾으려면 다시 칠해야합니다 (실제로 확실하지는 않지만 무엇이든).

어쨌든, 이것이 도움이되기를 바랍니다. 이 강조 아무것도 걸릴 것입니다 v, V또는 C-v, 첫 번째 줄은 주석 선택하면 그렇다면, 모든 강조 라인의 주석을 해제하려고를, 그렇지 않은 경우, 각 라인에 주석 문자의 추가 레이어를 추가합니다. 이것은 내가 원하는 행동입니다. 그 후 나를 위해 완벽하게 작동, 그래서 난 그냥,이 블록의 각 행은 주석 아닌지 여부를 전환하고 싶지 않았다 요구하는 여러 주제에 대한 질문.

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