Vim : 두 번째 행마다 삭제하는 방법?


답변:


105

이를 위해 매크로를 사용할 수 있습니다. 다음을 수행하십시오.

  • 명령 모드에서 시작하십시오.
  • 를 눌러 파일의 시작 부분으로 이동합니다 gg.
  • 를 누릅니다 qq.
  • 아래쪽 화살표를 클릭하고 dd뒤를 누릅니다 .
  • 를 누릅니다 q.
  • 프레스 10000@q

추신 : 명령 모드로 이동하려면 Escape를 몇 번 누르십시오.


11
물론 파일 길이가 20,000 라인 미만이라고 가정합니다. :-)
paxdiablo

3
사실 당신은 잘못된 마이클입니다. 이것은 VI가 파일 끝에 도달하자마자 매크로 실행을 중지하므로 완벽하게 작동합니다. 위의 샘플을 사용하여 매우 쉽게 시험해 볼 수 있습니다.
rui

1
글쎄, 다른 매크로와 마찬가지로 처음에는 올바르게 가져와야하지만 그 후에는 10000 @ q를 입력하여 모든 파일에 적용 할 수 있습니다. 어느 쪽이든 나는 그것이 단지 취향의 문제라고 믿기 때문에 철학적 논쟁을 시작하지 않을 것입니다. :)
rui

3
저는 '매크로'를 선호합니다. 매크로를 사용하여 특정 작업을 어떻게 해결하는지 '설명'하고 VIM이이를 반복하도록합니다. RUI, 화살표 키 대신 'j'를 사용하는 것을 선호합니다.
SolutionYogi

4
:g/^/+d사용자 stackoverflow.com/users/254635/ib(bellow )에서이 문제를 해결하는 더 우아한 방법입니다.
SergioAraujo 2011

256

작업을 수행하는 우아하고 효율적인 방법은 :+delete명령을 사용하여 모든 줄에서 현재 줄 다음 줄을 제거하는 명령 을 호출하는 것입니다 :global.

:g/^/+d

10
이 답변이 더 많은 찬성 투표를받지 못한 이유는 무엇입니까? 이것은 매우 깨끗하고 간단합니다. 또는 첫 번째 줄을 삭제하고 위의 명령을 실행하여 모든 홀수 줄을 삭제할 수 있습니다.
Usagi

3
@Usagi : 감사합니다! 나는 그것에 대해 똑같이 느낀다. 그리고 네, 절대적으로 맞습니다 :1d|g/^/+d. 홀수 줄을 삭제합니다.
ib.

@Usagi 다른 답변은 답변이 나오기 2 년 전에 '베스트 답변'으로 선정되었습니다. 또한 이것은 더 우아한 해결책이기는하지만 더 유용한 방법으로 작성되었을 수 있습니다 (즉, ^가하는 일에 대한 언급이 없지만 매크로는 누구나 이해하기 쉽습니다).
user1271772 2013 년

3
죄송합니다. 명령이 원하는 동작을 수행하는 방법에 대한 설명이 없으면 찬성하지 않고 대신 허용되는 답변을 선호합니다. 그 이유는 목표를 달성하는 방법을 이해하기 때문입니다. 남자에게 물고기를주는 것과 낚시하는 법을 가르치는 것의 차이입니다.
Gabe

3
몰라요.이 대답은 나를 나가서 : g 명령으로 낚시하는 법을 배웠습니다 (즉,이 페이지를 Google로 만들었습니다 -vim.wikia.com/wiki/Power_of_g ).
2014

67

주어진 일반 모드 명령을 사용 :normal하거나 :norm실행할 수 있습니다 . 출처.

:%norm jdd

15
이 답변은 충분한 관심을 끌지 못합니다. 아마도 여기와 연결된, 지저분한 치트 시트에 대한 설명이 없기 때문일 수 있습니다. norm 명령은 뒤에 오는 문자와 동일한 일반 모드 명령을 실행합니다. 따라서 여기에서는 j를 실행하여 한 줄 아래로 이동하고 dd를 실행하여 삭제합니다. 이 경우 'j'를 더 추가하여 X 번째 줄에 일반화 할 수 있습니다.
imoatama 2014 년

5
%는 1, $의 축약 형입니다 (1 행에서 끝까지 다음 명령을 실행)
Lambart

3
%norm ddj홀수 행을 삭제하려는 경우 왜 작동하지 않는지에 관심이 있습니다.
Cyker

10
:map ^o ddj^o
^o

여기서 ^는 CTRL을 의미합니다. 두 줄마다 한 줄을 삭제하는 재귀 매크로입니다. 첫 번째 줄을 잘 선택하면 완료됩니다.


8

에서 VIM 메일 아카이브 :

:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile

(vim 명령 줄에서 한 줄에 입력하려면 1,3,5,7, ... 행을 삭제합니다.)


4
그런 다음 선호합니다 !perl -ne 'print unless $. % 2':-)
Alex Brasetvik 2009

그리고 Alex, 나는 확실히 당신의 솔루션보다 내 솔루션을 선호하지만 이것은 여기에서 vim 자체만을 사용하는 유일한 현명한 솔루션이기 때문에 고려할 가치가 있습니다.
Michael Krelin-해커

매크로 방식은 훨씬 쉽습니다.
trusktr 2013

if (expression)모든 세 번째 줄에도 적용되는 유연성 때문에 +1 .
Jens

5

쉘 명령을 통해 항상 파이프 할 수 있습니다. 즉, 원하는 스크립팅 언어를 사용할 수 있습니다.

:%!perl -nle 'print if $. % 2'

(또는 원하는 줄에 따라 "if"대신 "unless"사용)


당신은 필요하지 않습니다 -l내가 그 말 것, 또한 ... 펄에 스위치를 awk훨씬 더 요즘,이 짧은 할 수있는 정말 아니에요하지만, 좀 더 널리 펄보다 : :%!awk NR\%2, 또는 :%!awk 1-NR\%2다른 라인.
ephemient

4
:%!awk -- '++c\%2'

대안으로

:%!awk -- 'c++\%2'

제거하려는 절반에 따라 다릅니다.


음, 기존 NR변수를 사용하지 않는 이유는 무엇입니까?
ephemient

권리. 잊었 으니까. ;-) 그러나 실제로 "적절한"변형은 NR에서 더 길어질 것입니다. 그리고 멋지게 보이는 두 사람은 없을 것 입니다.
Michael Krelin-해커

:%!awk NR\%2또는 :%!awk 1-NR\%2, 다른 댓글에 게시했습니다. 그것은 거의 길지 않습니다.
ephemient

1
1-NR보다 깁니다 c++. 네, 한 캐릭터라는 걸 알아요. 내가 말했듯이 – 진짜 이유는 내가 그것을 잊었 기 때문입니다. 어쨌든 사람들은 여기에서 awk의 아름다움에 감사하지 않는 것 같습니다.
Michael Krelin-해커

그리고 NR보다 짧습니다 ++c:)
ephemient

3

다음과 같이 Vim의 자체 검색 및 대체 기능을 사용할 수 있습니다. 커서를 첫 번째 줄에 놓고 일반 모드로 입력합니다.

:.,/fff/s/\n.*\(\n.*\)/\1/g
  • .,/fff/대체의 범위이다. "이 줄에서 정규식과 일치하는 줄 fff(이 경우 마지막 줄) 까지"을 의미 합니다.
  • s///대체 명령입니다. 정규식을 찾고 모든 항목을 문자열로 바꿉니다. g단부 수단으로는 긴 정규식 발견되는 유지로 교체를 반복한다.
  • 정규식 \n.*\(\n.*\)은 줄 바꿈, 전체 줄 ( .*줄 바꿈을 제외한 모든 문자와 일치), 다른 줄 바꿈 및 다른 줄과 일치합니다. 괄호\(\) 표현식이 기록되도록하므로 나중에 \1.
  • \1 그룹화 된 줄 바꿈과 그 뒤에 줄을 삽입합니다. 왜냐하면 다음 줄도 사라지는 것을 원하지 않기 때문입니다. 우리는 대체 메커니즘이 지나가길 원하므로 다음 대체에서 삭제하지 않습니다.

이렇게하면 삭제를 수행 할 범위를 제어 할 수 있으며 외부 도구를 사용할 필요가 없습니다.


또는 $대신 /fff/파일의 내용에 관계없이 파일 끝의 경우.
ephemient

3

또 다른 접근 방식으로 vim이 지원하는 경우 파이썬을 사용할 수도 있습니다.

:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]

b = cb[:]현재 버퍼의 모든 행을에 임시로 복사합니다 b. b[::2]버퍼에서 매 두 번째 줄을 가져 와서 현재 버퍼 전체에 할당합니다 cb[:]. b버퍼 객체가 확장 된 슬라이스 구문을 지원하지 않는 것 같으므로 복사 가 필요합니다.

이것은 아마도 "vim 방식"은 아니지만 파이썬을 알고 있다면 기억하기 더 쉬울 것입니다.


2

홀수 줄 (1,3,5, ..)을 삭제하려면-> :%s/\(.*\)\n\(.*\)\n/\2\r/g

짝수 줄 (2,4,6, ..)을 삭제하려면-> :%s/\(.*\)\n.*\n/\1\r/g

텍스트 (첫 번째 줄 형성), 새 줄 문자 및 더 많은 텍스트 (두 번째 줄 형성)와 다른 줄 바꾸기 문자를 검색하고 위의 내용을 첫 번째 일치 (홀수 줄) 또는 두 번째 일치 (짝수 줄)로 바꿉니다. 뒤에 캐리지 리턴.


0

sed를 호출합니다.

:% !sed -e '2~2 d'

^^^^                  pipe file through a shell command
    ^^^^^^            the command is sed, and -e describes an expression as parameter
            ^^^^^     starting with the second line, delete every second line

-1

해결책

당신은 vim에서 이것을 시도 할 수 있습니다

:1,$-1g/^/+1d

편집하다

더 명확하게해볼 게 (두 부분)

첫 번째 부분 선택 범위 ( :from,to)
두 번째 부분 작업 ( d삭제)

  • 첫 번째 줄에서 마지막 줄까지의 범위이지만 한 줄 (:1,$-1 )
  • globaly ( g) delete ( +1d) 다음 줄

파일의 첫 번째 줄로 이동하고 실행 :+1d하면 다음 줄이 사라지는 것을 볼 수 있습니다.

나는 그것이 진흙탕이라는 것을 알고 있지만 그것은 vim이고 작동합니다.


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