4 줄마다 반대로하는 방법?


13

우선, 여기에 첫 번째 게시물이 있기 때문에 VIM이 훌륭한 도구이고 여기에 포럼이 도움이되는 많은 사람들과 함께 질문에 대한 답변을 찾는 데 매우 도움이되었다고 말하고 싶습니다. 귀중한 도움. 저는 여전히 VIM을 처음 접하기 때문에 제가 배운 모든 것이 여기에서 나왔습니다.

내 질문은 : 파일의 모든 줄을 뒤집는 방법을 알고 있지만 (다른 방법 중 : g / ^ / m0) 파일의 모든 4 줄을 뒤집는 방법이 있으므로

line1
line2
line3
line4
line5
line6
line7
line8
...

된다

line4
line3
line2
line1
line8
line7
line6
line5
...

이러한 파일에는 항상 4 줄의 정확한 배수가 있다고 가정 할 수 있습니다.


2
"ps"정보 : 한 줄 앞에 4 개의 공백을 삽입하면 코드로 해석됩니다 (텍스트를 선택하고 상단의 형식 단추를 사용할 수 있음). 심문 아이콘에 대한 자세한 내용 은 상단 에서 확인할 수 있습니다 .
mMontu

답변:


15

Vim Wiki에:Reverse 설명 된 명령을 사용할 수 있습니다 ( 영구적으로 포함 시키기 위해 포함시킬 수 있음 )..vimrc

command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl

그런 다음 4 줄마다 매크로를 기록하여 명령을 실행할 수 있습니다.

qmV3j:Reverse<cr>4jq
1000@m

설명:

  • qm: 일반 모드에서 'q'는 주어진 레지스터에서 매크로 기록을 시작 (및 중지)합니다 (이 경우 레지스터 'm'이지만 다른 문자 일 수 있음)
  • V: 비주얼 모드로 들어가서 현재 줄을 선택하십시오
  • 3j: 시각적 선택을 다음 3 줄로 확장
  • :Reverse<cr>: 선택한 줄에서 Reverse 명령을 실행하십시오 ( <cr>여기서는 enter키를 나타냄).
  • 4j: 변경되지 않은 다음 줄로 이동
  • q: 매크로 기록을 중지합니다
  • 1000@m: 레지스터 'm'에 기록 된 매크로를 1000 번 실행합니다 (파일이 4000 줄보다 큰 경우이 수를 늘릴 수 있음)

편집하다:

주석에서 언급했듯이 카운트를 사용하는 대신 재귀 매크로를 사용할 수 있습니다.

qmV3j:Reverse<cr>4jq
qM@mq
@m
  • qM: 지정된 레지스터 q가 대문자 인 경우 매크로가 레지스터에 추가 됩니다 (복잡한 매크로에서 마지막 단계를 놓쳤을 때 알 때도 유용함).
  • @m: 레지스터에서 매크로 실행 m
  • q: 매크로 추가 중지

매크로로 생성되었지만 워크 플로에서 일반적인 작업 인 경우이 명령을 만들 수 있습니다.

function! Reverse4()
   let reg_m = @m
   let @m = '<c-r><c-r>m'
   normal! @m
   let @m = reg_m
endfunction
command! Reverse4 call Reverse4()
  • function! Reverse4()/ endfunction: 새로운 함수를 정의
  • let reg_m = @m: 레지스터의 현재 내용을 저장합니다 m
  • let @m = "<c-r><c-r>m": 레지스터에서 매크로 삽입 m- 노트 <c-r>의 정력 표기법 Ctrl+ r당신이해야 입력 하여 라인이 유사합니다, 그래서이, 복사 / 붙여 넣기하지 let @m = 'V3j:Reverse^M4j@m'그리고이 포함됩니다 특수 문자 (^ M)
  • normal! @m: 일반 명령은 일반 모드에서 입력 한대로 인수를 실행하므로 재귀 매크로를 실행합니다.
  • let @m = reg_m: 레지스터의 내용을 복원하므로이 레지스터 m에서이 레지스터를 사용하고 있다는 것을 기억할 필요가 없습니다.

  • command! Reverse4 call Reverse4():이 함수에 대한 새 명령을 작성하십시오

필요에 따라 다음과 같이 향상시킬 수 있습니다. 예 : 명령 및 함수에 인수를 전달하여 4 행 그룹으로 고정되는 대신 여러 행에서 작동하도록합니다.


1000@q해킹 대신 재귀 매크로를 사용할 수도 있습니다 qmqqm ... @mq@m.
손잡이

"qmV3j : Reverse <cr> 4jq"를 실행하려고 할 때 "E492 : 편집기 명령이 아닙니다"라고 말했습니다. 나는 뭔가 잘못하고 있어야합니다. 그건 그렇고 GVIM을 사용하고 있으며 이제까지 만 사용했습니다. 나는 처음에 그것을 언급 했어야했다.
ablewasiereisawelba

아, 괜찮아 "qmV3j : Reverse <cr> 4jq"부분 앞에 ":"을 입력하지 않아야합니다. 효과가 있었다! 대단히 감사합니다, mMontu. 질문 할 수있는 경우 .vimrc에 ": Reverse"명령을 어떻게 포함합니까?
ablewasiereisawelba

3
@ablewasiereisawelba 명령을 영구적으로 사용 가능하게하려면 command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohlvimrc 어딘가에 행을 작성하십시오 .
saginaw

@ saginaw 아, 나는 그것이 그렇게 간단하다는 것을 몰랐다. 감사합니다.
ablewasiereisawelba

9

모든 반복 작업 과 마찬가지로 기본 편집 작업으로 무언가를 한 번 수행 할 수 있으면 매크로를 기록하여 여러 번 쉽게 수행 할 수 있습니다.

(이 경우에는 재귀 매크로를 사용하지만 비 재귀 매크로를 기록하고 망치로 @@또는 카운트를 사용하여 여러 번 재생할 수 있습니다.)

ggqqqqqddjjpkddkkPjddpjj@qq@q

세분화

  1. gg: 파일의 시작 부분으로 이동합니다.
  2. qqq: 레지스터를 지 웁니다 q. 5 단계에서 왜 이것이 필요한지 살펴 보겠습니다.
  3. qq: 매크로 등록을 시작하여 q 등록
  4. ddjjpkddkkPjddpjj: 처음 네 줄을 수동으로 삭제하고 붙여 넣어 순서를 변경하는 일련의 작업입니다. (이것은 언뜻 보면 복잡해 보일 수 있지만 속지 않는이 첫 번째 5 분에서 배운 또는 한 것 매우 기본적인 것들입니다 그래서의. vimtutor: j, k, dd, p, P)
  5. @q: 매크로를 불러! 이 시점에서 register q에는 아무것도 포함되지 않으므로 (2 단계에서 지웠으므로) 아무 일도 일어나지 않습니다.
  6. q: 매크로 기록을 중지합니다.
  7. @q: 필요에 따라 재귀 매크로를 여러 번 재생하십시오.

NB 파일에 정확히 4로 나눌 수없는 여러 줄이 들어 있으면 위의 결과는 원하는 결과를 얻지 못합니다. 4 줄이 남아 있지 않은 경우 매크로를 일찍 중지하려면 4 단계에서 편집 내용을 적용 하기 전에 실패 할 Vim 표준 모드 명령을 수행해야합니다. 아래로 이동하여이 작업을 수행 할 수 있습니다. 우리가 줄을 움직이기 시작하기 전에 3 번 (그리고 다시) 줄 :jjj3k

그러므로:

ggqqqqqjjj3kddjjpkddkkPjddpjj@qq@q

레지스터 q를 명시 적으로 지우는 이유는 무엇입니까? 당신이 그것에 기록한다면, 거기에 있던 것은 어쨌든 덮어 쓸 것입니다 ....
Wildcard

4
@Wildcard 재귀 매크로이므로 register의 내용을 처음 호출 할 q때 비어 있어야합니다. 그렇지 않으면 버전이 엉망이됩니다.
saginaw

아주 좋아요 나는 명령의 정확한 순서를 입력하지 않고 대화식으로 이것을 시도하고 다음을 사용하여 상처를 입었다.qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
Wildcard

1
@ablewasiereisawelba- where I can just use the one-line custom command each time I need to do this매크로를 vimrc에 함수 / 명령으로 저장할 수 있으므로 매크로를 사용할 때마다 다시 만들 필요가 없습니다.
mMontu

1
@ablewasiereisawelba "편집"이 유용하다는 것을 알게되어 기쁩니다! 이것이 첫 번째 게시물이므로 StackExchange 알림의 작동 방식을 알지 못할 수 있습니다. 의견을 게시하면 답변 / 질문 작성자가 알림을받습니다. @ <nick>을 포함하는 경우에만 다른 사람에게 알림이 전송됩니다. 따라서 리치 만 마지막 메시지에 대한 알림을 받았습니다.
mMontu

7

외부 필터로 Ex사용 하는 명령을 사용 하여이 작업을 수행 할 수도 있습니다 sed.

:%!sed -n 'h;n;G;h;n;G;h;n;G;p'

이 버전은 4의 배수를 초과하는 추가 행을 무시 (삭제)합니다. 마지막 4 행 미만 (역전)을 유지하려면 다음을 사용하십시오.

:%!sed -n '$p;h;n;G;$p;h;n;G;$p;h;n;G;p'

%여기에 "버퍼의 모든 라인"을 의미합니다.

!명령 수단은 "입력으로 지정된 라인의 다음 명령을 실행하고, 대체 명령의 출력이 지정된 라인." (필터라고 부릅니다. 예를 들어 :%!sort파일의 모든 행을 정렬하고 :2,8!sort2-8 행을 정렬하는 등 정렬과 같은 작업에 매우 편리합니다 .)

sed는 IS 스트림 편집기 도구를 모든 유닉스 계열 시스템에 있습니다. 여기서 sed사용되는 주요 개념은 "패턴 공간"(기본적으로 입력의 각 줄을 차례로 포함 함)과 "보유 공간"(다른 공간 sed을 처리 하는 동안 사용하여 추가 텍스트 를 저장 하는 데 사용할 수있는 공간)입니다. 입력 라인).

-nsed패턴 공간을 인쇄하는 기본 동작을 억제 하는 명령 의 옵션입니다 (이 경우 명시 적으로 말할 때만 인쇄하기 때문에).

$psed명령 에서 "의 마지막 행에있는 경우 sed인쇄하십시오 (패턴 공간)".

h "홀드 스페이스"에있는 '패턴 스페이스'의 현재 내용을 붙여서 존재하는 내용을 덮어 씁니다. "

n "패턴 공간"의 내용을 입력에서 다음 줄로 바꾸십시오. "

G " '패턴 공간'에 추가 : 줄 바꿈 뒤에 '보유 공간'의 내용이 추가됨"을 의미합니다.

모두 합쳐서, sed명령은 네 줄의 출력을 저장하고, 저장하는대로 되 돌린 다음 인쇄합니다. $p번째 버전에서 추가 명령은 파일의 마지막 행은 4 개의 배수 라인에 이외 도달하면, 라인은 여전히 인쇄되도록.


Vim 관련 기능을 사용하지 않고 외부 필터를 사용하지 않는 대체 대화식 접근 방식의 경우 :

:4

네 번째 줄로 이동합니다.

:.m -4 | +3m . | +2m . | +5

앞의 네 줄 (1-4)을 뒤집고 커서를 줄 8에 둡니다.

.m -4단지 현재 라인으로 이동 한 후 (이동 된 줄에 커서를 떠나) 라인 네 개의 선 다시.

+3m .커서를 이동 한 줄에 그대로두고 현재 줄 바로 다음 으로 3 행인 줄 현재 줄 바로 다음으로 이동합니다. +2m .물론 동일하게 작동합니다.

+5 커서를 원래 위치에서 다섯 줄 아래로 놓습니다.

원하는대로 반복하십시오.

Vim에서이 전체 명령을 @:로 반복 한 다음로 다시 반복 할 수 있습니다 @@. POSIX에서 vi또는 ex당신이해야 삽입 :.m -4 | +3m . | +2m . | +5 , 텍스트 행으로 명명 된 버퍼 (레지스터)에 삭제 한 다음 명명 된 버퍼 (레지스터)를 실행합니다.

따라서 ex모드에서 POSIX 지정 기능 만 사용하여 대화식으로 줄을 바꾸고 17 줄의 텍스트로 시작합니다.

Entering Ex mode.  Type "visual" to go to Normal mode.
:0a     # Append following text after "line 0" (i.e. insert at start of file).
.m -4 | +3m . | +2m . | +5
.       # End text insertion
:d k    # Delete that line to register k
line1   # This is a printout of the current line
:4      # Move to line 4
line4
:@k     # Execute register k to reverse lines 1-4
line8
:@@     # Execute register k again
line12
:@@     # Execute register k again
line16
:@@     # Execute register k again
line17
:%p     # Print the whole buffer (just to see what was done)
line4
line3
line2
line1
line8
line7
line6
line5
line12
line11
line10
line9
line16
line15
line14
line13
line17
:wq     # Save and quit

더 읽을 거리 :


해결책을 좀 더 설명해 주시겠습니까?
vappolinario

3
@ vappolinario, 추가 설명을 추가했습니다. 도움이 되나요? :)
와일드 카드

와우, 긴 답변입니다. :) 나는 실제로 sed를 사용했지만, 어딘가에서 찾은 하나의 간단한 스크립트와 함께 사용했습니다. 그러나 제안 된 줄을 실행하려고하면 " 'sed'는 내부 또는 외부 명령, 작동 가능한 프로그램 또는 배치 파일로 인식되지 않습니다." vim 폴더 또는 sed에 sed가 필요한지 확실하지 않습니다.
ablewasiereisawelba

1
@ablewasiereisawelba, Windows 상자에서 실행 중이고 Cygwin (또는 MobaXterm 또는 이와 유사한 것)을 사용하지 않으면 내가 준 다른 방법을 시도 할 수 있습니다. 4G:.m -4 | +3m . | +2m . | +5<Enter>@:그런 다음 @@파일이 완전히 처리 될 때까지 반복하십시오. 그래도 MobaXterm을 설치하는 것이 좋습니다. :)
와일드 카드

@Wildcard 오, 알았어, 지금 MobaXterm을 확인하고 있습니다. :)
ablewasiereisawelba

7
:g/^/exe 'm .-' . substitute(line('.') % 4, '^0$', '4', '')

일반 영어 : 모든 라인의 경우, 현재 행을 이동 lnum % 4하지 않는 한, lnum % 4 == 0이 경우 현재 라인을 이동 4.

또한 모든 n줄 을 반대로 바꾸 4려면 위 명령에서의을로 바꿉니다 n.


2
아주 좋은 한 줄 명령입니다. djjcast 감사합니다.
ablewasiereisawelba
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.