[linux] Vim 또는 Linux에서 공백을 탭으로 변환하려면 어떻게해야합니까?

Stack Overflow에서 필요한 것을 찾지 않고 공백을 탭으로 변환하는 방법에 대한 몇 가지 질문을 살펴 보았습니다. 탭을 공백으로 변환하는 방법에 대한 추가 질문이 있지만 그 반대의 방법을 시도하고 있습니다.

에서 Vim내가 해봤 :retab:retab!행운을하지 않고 있지만, 내가 믿는 사람들은 어쨌든 공간으로 탭에서 진행을 위해 사실이다.

난 둘 다 노력 expandunexpand운이없이 명령 프롬프트에서.

문제의 파일은 다음과 같습니다.

http://gdata-python-client.googlecode.com/hg-history/a9ed9edefd61a0ba0e18c43e448472051821003a/samples/docs/docs_v3_example.py

또는 셸을 사용하여 선행 공백을 탭으로 변환하려면 어떻게 Vim해야합니까?



답변

Vim을 사용하여 모든 선행 공백 을 확장하면 (보다 큼 'tabstop') 사용하는 retab것이 옳았 지만 먼저 'expandtab'재설정 :verbose set ts? et?해야합니다 (친구입니다). retab걸리는 범위를 나는 보통 지정할 수 있도록, %“전체 파일”을 의미 할 수 있습니다.

:set tabstop=2      " To match the sample file
:set noexpandtab    " Use tabs, not spaces
:%retab!            " Retabulate the whole file

이와 같은 작업 (특히 Python 파일에서)을 수행하기 전에 일반적으로을 설정 하여 공백과 변경 사항을 'list' 수 있습니다.

난에 다음과 같은 매핑이 .vimrc 이를 들어 :

nnoremap    <F2> :<C-U>setlocal lcs=tab:>-,trail:-,eol:$ list! list? <CR>


답변

1- 공백이 있고 탭을 원하는 경우

먼저, 하나의 탭을 가질 공간 수를 결정해야합니다. 즉, 앞에 4 개의 공백이있는 줄이 있다고 가정하거나 8 … 탭이 4 개의 공백이되기를 원할 것입니다. 이제 그 정보로 다음을 수행하십시오.

:set ts=4
:set noet
:%retab!

여기에 문제가 있습니다! 이 일련의 명령은 줄의 시작 부분에 공백뿐만 아니라 모든 텍스트를 찾습니다. 그것은 다음과 같은 문자열을 의미합니다 : "Hey,␣this␣␣␣␣is␣4␣spaces"will 될 "Hey,␣this⇥is␣4␣spaces"것이지만 그렇지는 않습니다! 그 탭!.

이 작은 문제를 해결하기 위해 search대신을 추천합니다 retab.

:%s/^\(^I*\)␣␣␣␣/\1^I/g

이 검색은 전체 파일에서 탭 수로 시작하여 4 개의 공백으로 시작하는 행을 찾은 다음 찾은 탭 수에 1을 더한 값으로 대체합니다.

불행히도 이것은 한 번에 실행되지 않습니다!

처음에는 파일에 공백으로 시작하는 줄이 있습니다. 그러면 검색은 처음 4 개의 공백 만 탭으로 변환하고 다음을 수행합니다.

명령을 반복해야합니다. 몇 번이나? 당신이 얻을 때까지 pattern not found. 아직 프로세스를 자동화하는 방법을 생각할 수 없습니다. 그러나 당신이 할 경우 :

`10@:`

아마 끝났을 것입니다. 이 명령은 마지막 검색 / 바꾸기를 10 번 반복합니다. 프로그램에 너무 많은 들여 쓰기가 없을 것입니다. 그렇다면 다시 반복하십시오 @@.

이제 답을 완성하십시오. 나는 당신이 반대를 요구했다는 것을 알고 있지만, 언제 일을 취소해야하는지 결코 알지 못합니다.

2 탭이 있고 공백이 필요합니다.

먼저 탭을 변환 할 공간 수를 결정하십시오. 각 탭을 2 칸으로하고 싶다고합시다. 그런 다음 다음을 수행하십시오.

:set ts=2
:set et
:%retab!

이것은 문자열과 같은 문제가 있습니다. 그러나 문자열 내부에서 하드 탭을 사용하지 않는 더 좋은 프로그래밍 스타일로 실제로 여기서 좋은 일을하고 있습니다. 문자열 안에 탭이 정말로 필요하다면을 사용하십시오 \t.


답변

:%s/\(^\s*\)\@<=    /\t/g

번역 : 4 개의 연속 공백 (= 문자 뒤)의 모든 인스턴스를 검색하지만 해당 지점까지의 전체 행이 공백 인 경우에만 해당됩니다 (이는 너비가 0 인 룩 어설 션 어설 션을 사용함 \@<=). 찾은 각 인스턴스를 탭 문자로 바꾸십시오.


답변

모든 공백을 탭으로 변경합니다 : % s / \ s / \ t / g


답변

리눅스 : with unexpand(andexpand )

https://stackoverflow.com/a/11094620/1115187 매우 유용한 솔루션입니다. 주로 * nix-utilities를 사용하기 때문입니다.

  1. 펼치기 — 공백-> 탭
  2. 확장 — 탭-> 공백

리눅스 : 커스텀 스크립트

내 원래 답변

4 개의 공백 들여 쓰기 ( {4}스크립트 에는 2 개 있음)를 폴더의 모든 .py파일에있는 탭 ./app(재귀 적으로)으로 바꾸는 배쉬 스 니펫 :

find ./app -iname '*.py' -type f \
    -exec awk -i inplace \
    '{ match($0, /^(( {4})*)(.*?)$/, arr); gsub(/ {4}/, "\t", arr[1]) }; { print arr[1] arr[3] }' {} \;

가운데 나 끝에있는 4 개의 공백은 수정하지 않습니다.

Ubuntu 16.0x 및 Linux Mint 18에서 테스트되었습니다.


답변

필자의 경우 탭으로 대체하려는 여러 공백 (필드가 하나 이상의 공백으로 구분됨)이있었습니다. 다음과 같이했습니다.

:% s/\s\+/\t/g


답변

GNU coreutils가 설치되어 %!unexpand --first-only있거나 4 개의 공백 탭을 고려한 경우 %!unexpand -t 4 --first-only( --first-only실수로 호출 unexpand한 경우에만 있음)을 고려하십시오 --all.

이는 지정된 탭 정지 앞의 공백 만 대체하고 그 다음 공백은 대체 하지 않습니다 . 문자 그대로 탭을 표시하지 않으면 vim에 시각적 차이가 없습니다. 예를 들어, 내 ~/.vimrc포함 set list listchars=tab:▸┈(이것이 당신이 unexpand작동하지 않았다고 생각하는 이유입니다 ).