파일의 모든 줄에서 후행 공백을 제거하는 가장 간단한 방법은 무엇입니까?


139

줄 끝에 끝에 공백이있는 파일을 찾기 위해 텍스트 파일을 프로그래밍하거나 열 때 매우 일반적입니다. 정력는 설정하여이를 표시 할 수있는 방법이 trail에서 옵션 listchars옵션을 다음 회전 list에 있습니다.

그러나 파일 전체에서 전역 적으로 후행 공백을 제거하는 가장 쉬운 방법은 무엇입니까?



다음은 주제에 대한 문서 항목 입니다.
Filipp W.

vim-faq를 설치 한 경우 오프라인 답변을 얻을 수 있습니다 : :h vim-faq및 검색 /trailing. 기억하기 어려운 태그는 :h faq-12.1입니다.
Hotschke

답변:


72

모든 후행 공백을 제거하려면 키 바인딩을 사용하십시오.

내가 편집하는 일부 페이지에는 실제로 공백 문자 (예 : 마크 다운)가 필요하고 다른 페이지에는 공백이 필요하지 않으므로 F5자동으로하지 않고 사소한 키 바인딩을 설정합니다 . 이렇게하려면 아래 코드 (vim.wikia에서) 또는 그 변형을 다음에 추가하십시오 .vimrc.

"Remove all trailing whitespace by pressing F5
nnoremap <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR>
  • nnoremap <F5>F5정상 모드 에서 키 에 비 재귀 매핑을 수행 합니다.
  • :let _s=@/매크로에서 마지막 검색어를 @/변수에 저장합니다._s
  • <Bar>|명령을 분리하기 위한 파이프 기호 로 기능 하지만 |이 컨텍스트에서 명령을 종료하므로 <Bar>대신 사용해야합니다.
  • :%s/\s\+$//e후행 공백을 검색하고 버퍼의 모든 위치에서 삭제합니다 ( 이 표현식에 대한 자세한 분석 은 CarpetSmoker의 답변 참조 ).
  • let @/=_s마지막 검색어를 매크로로 복원하여 @/다음에 방문 할 때 사용할 수 있도록합니다 n.
  • <CR> 매핑을 종료합니다

또는 더 선택적

후행 공백을 모두 제거하지 않으려는 경우 패턴을 사용하여보다 선택적 일 수 있습니다. 예를 들어 다음 코드는 세미콜론 뒤에 오는 경우에만 후행 공백을 제거하는 방법을 보여줍니다 (여기에 묶여 있음 F8).

nnoremap <F8> :let _s=@/<Bar>:%s/;\s\+$/;/e<Bar>:let @/=_s<Bar><CR>

이것은 나와 같이 마크 다운과 같은 heredocs가 있는 파일이 세미콜론으로 끝나는 프로그래밍 문 사이에 산재되어있는 경우 유용합니다 .


6
:keeppatterns재정의를 방지 하십시오 @/. 또한 살펴보십시오 :keepjumps.
Bohr

@Bohr 어떤 버전의 vim을 사용하고 있습니까? 나는 시도했지만 :help keeppattern아무것도 얻지 못했습니다.
Christopher Bottoms

@ChristopherBottoms 버전 7.4.155 이상 .
Bohr

@Bohr. 감사! 내가 여전히 7.4.0을 사용하고 있음을 알게되었습니다. 최신 버전을 설치했으며 사용할 수 있습니다.
Christopher Bottoms

2
다음 마지막 검색어가 자동으로 약 정처없는이 방법 :-) 복원되기 때문에 당신은 함수에서이 명령을 포장하여 같은 효과를 얻을 수 있습니다 :nohl당신이 뭔가를 강조한다면, 그것은 강조 유지할 경우, 중 (업데이트 된 답변 참조).
Martin Tournoij 2016 년

175

가장 간단한 방법은 다음을 사용하는 것입니다 :substitute.

:%s/\s\+$//e
  • :%s전체 버퍼 인 :substituterange 를 실행 %합니다.
  • \s t 모든 공백 문자와 일치합니다.
  • \+ 1 회 이상 반복하십시오.
  • $ 줄의 끝에 고정합니다.
  • e(파일이 후행 공백없이 이미 IE) 일치가없는 경우 플래그는 오류를 포기하지합니다.

그러나 이것은 두 가지 부작용을 유발하므로 "최상의"방법이 아닐 수도 있습니다.

  1. 커서를 마지막 일치 항목으로 이동합니다.
  2. 명령을 내역 및 검색 내역에 추가합니다.
  3. 마지막 검색어를 재설정합니다.

이것을 기능으로 바꾸면 두 항목을 모두 고칠 수 있습니다.

fun! TrimWhitespace()
    let l:save = winsaveview()
    keeppatterns %s/\s\+$//e
    call winrestview(l:save)
endfun

그런 다음 다음과 같이 사용하십시오.

:call TrimWhitespace()
  1. winsaveview(), 커서의 위치를 포함하는 주름의 등, 점프 현재 "보기", 저장됩니다 winrestview()끝이 저장된 변수에서이 복원됩니다.
  2. :keeppatterns방지 \s\+$검색 기록에 추가되는 패턴.
  3. 마지막으로 사용한 검색어는 함수를 떠난 후 자동으로 복원되므로이를 위해 다른 작업을 수행 할 필요가 없습니다.

이것은 :call항상 타이핑 하는 것이 다소 성가 시므로 명령을 정의 할 수 있습니다.

command! TrimWhitespace call TrimWhitespace()

다음없이 사용할 수 있습니다 :call:

:TrimWitespace

물론 키에 바인딩 할 수도 있습니다.

:noremap <Leader>w :call TrimWhitespace()<CR>

어떤 사람들은 파일을 디스크에 쓰기 전에 자동으로 이렇게하기를 좋아합니다.

autocmd BufWritePre * :call TrimWhitespace()

마음에 들지 않습니다. 일부 형식에는 후행 공백 (예 : Markdown)이 필요하고 다른 경우에는 코드에서 공백 문자 (예 : 전자 메일 형식 지정 및 --<Space>마커를 사용하여 서명의 시작을 나타내는 경우)를 원할 수도 있습니다. ).


뻔뻔한 플러그 모드 : 얼마 전에 전체 프로젝트의 공백을 한 번에 정리 하는 작은 Python 스크립트작성했습니다 .


1
이전 위치로 이동하는 기능을 생성하지 않으려면 ​`​교체가 완료된 후을 두 번 누르십시오 . 이렇게하면 다음과 같은 oneliner를 만들 수 있습니다.%s/\s\+$//e | exe "normal ``"
Neaţu Ovidiu Gabriel

1
@ NeaţuOvidiuGabriel은 물론 oneliner가 실행 된 후 이중 백틱이 동일하게 작동하지 않습니다. ;)
와일드 카드

비슷한 : stackoverflow.com/a/1618401 . 그러나 나는 Martin의 코드를 더 좋아합니다.
john cj

11

각 줄의 끝에있는 모든 공백을 삭제하려면 다음 명령을 사용하십시오.

:%s/ \+$//

탭을 포함하려면 \s공백 대신 사용하십시오 .


명령 행에서 :

$ ex +'%s/\s\+$//e' -cwq file.c

현재 디렉토리의 모든 파일 (재귀 적으로 사용 **/*.*) :

$ ex +'bufdo!%s/\s\+$//e' -cxa *.*

파이썬 방법 :

:py import vim
:pydo vim.current.buffer[linenr - 1] = vim.current.buffer[linenr - 1].strip()

또는:

:py import vim
:py for i, l in enumerate(vim.current.buffer): vim.current.buffer[i] = l.rstrip()

사용 lstrip()왼쪽 스트립 (후미)에 대한 rstrip()권리 스트립 (선도) 또는 strip()양쪽 끝에서 제거 할 수 있습니다.


다음은 추가 할 수있는 줄 끝에서 불필요한 공백을 제거하는 유용한 기능입니다 .vimrc.

" Removes superfluous white space from the end of a line
function! RemoveWhiteSpace()
   :%s/\s*$//g
    :'^
    "`.
endfunction

이를 위한 DeleteTrailingWhitespace 플러그인 도 있습니다 .


공백 강조

후행 공백이 모두 사라 졌는지 다시 확인하려면 다음을 사용하십시오.

  1. 입력 / $하여 찾으십시오. vim이 있다면 vim이이를 강조 표시합니다.

  2. 색상을 사용하여 강조 표시하십시오.

    :highlight ws ctermbg=red guibg=red
    :match ws /\s\+$/
    
  3. 보이는 문자 ( source )를 사용하십시오 .

    :set encoding=utf-8
    :set listchars=trail:·
    :set list
    

참조 : 불필요한 공간 강조

기본적으로 후행 공백을 강조 표시하려면 .vimrc다음과 같이 구성하십시오 .

highlight ws ctermbg=red guibg=red
match ws /\s\+$/
autocmd BufWinEnter * match ws / \+$/

기본적으로 공백 제거

저장시 파일의 모든 후행 공백이 자동으로 제거되도록하려면 다음 명령을에 추가하십시오 .vimrc.

autocmd BufWritePre *.c,*.php :%s/ \+$//ge

사용자가 저장하는 모든 파일에서 공백을 제거하기 때문에 권장하지 않습니다 (공백이 필요한 경우에도).


또한보십시오:


5

에 Exapnding 크리스토퍼 바지의 대답은 조금 : 조나단 Palardy는 이에 좋은 기사를 썼다 . 여기 Preserve(command)에 임의의 명령을 실행하는 동안 편집기 상태 (주로 커서 위치 및 마지막 검색 패턴)를 유지 하는 함수를 작성합니다 .

function! Preserve(command)
  " Preparation: save window state
  let l:saved_winview = winsaveview()
  " Run the command:
  execute a:command
  " Clean up: restore previous window position
  call winrestview(l:saved_winview)
endfunction

이것은 다목적이라는 장점이 있습니다. 예를 들어, Jonathan이하는 것처럼 모든 후행 공백을 다음과 같이 매핑하여 사용할 수 있습니다.

nnoremap <F5> :call Preserve("%s/\\s\\+$//e")<CR>

시각적 모드 매핑에 사용하여 시각적으로 선택된 선에서 후행 공백 만 제거 할 수도 있습니다.

xnoremap <F5> :call Preserve("'<,'>s/\\s\\+$//e")<CR>

그리고 =장소를 유지하면서 전체 문서 형식을 지정하는 등 다른 전화에 사용할 수 있습니다 (충돌하지 않도록 이번에는 다른 키를 사용하십시오).

nnoremap <F6> :call Preserve("normal gg=G")<CR>

전부해서, 나는 그 Preserve(command)기능이 훌륭한 도구라는 것을 알았습니다 .


2
마지막으로 사용한 검색어는 함수를 떠날 때 자동으로 유지됩니다. 따라서 @/(이 경우 어쨌든) 과 관련한 문제가 없어야합니다.
Martin Tournoij 2016 년

3
winsaveview()그리고 winrestview()훨씬 우수합니다.
dash-tom-bang

맞아! 귀하의 의견에 따라 업데이트되었습니다.
Alex

0

StripTrailingSpaces 함수의 다른 버전 :

if !exists('*StripTrailingWhitespace')
    function! StripTrailingWhitespace() range
        if !&binary && &filetype != 'diff'
            call Preserve(":" . a:firstline . "," . a:lastline . "s/\\s\\+$//e")
        endif
    endfunction
endif

실제로이 기능에는 버그가 있습니다 (이 기능). "범위"옵션으로 인해 위치가 유지되지 않습니다. 그것은 잘 작동하지만 제거되어 도움을 받기 위해 코드를 공유하고 있습니다.

보시다시피 위 의 보존 기능을 사용 하지만 약간 다른 방식으로 사용됩니다.

차이점은 줄 범위 나 단락 범위를 선택 하면 명령 프롬프트에 vip범위 :'<,'>가 자동으로 나타납니다.

아이디어는 Bez Hermoso 포스트 에서 나왔습니다 .

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