파일에 영구적 인 줄 번호를 추가하는 방법?


21

이와 같은 텍스트 파일이 있습니다 (Windows에서 gVim 사용)

foo bar baz quux 
corge grault garply 
waldo fred plugh 
[...150 more lines...]
xyzzy thud

파일의 각 줄에 숫자를 추가하고 싶습니다. 를 사용하지 않고 :set number다음과 같이 각 줄 앞에 텍스트로 숫자를 추가하려면 숫자가 파일의 일부입니다.

1. foo bar baz quux 
2. corge grault garply 
3. waldo fred plugh 
[...~150 more lines...]
155. xyzzy thud

awk아마도이 직업을위한 도구 일 것입니다. 그러나 나는 Windows에 있습니다 (한숨).
roblogic

답변 이미 여기에 :), 결코 마음
roblogic

1
아마도 .. 아니면 이것이 더 일반적인가?
muru

비슷하지만 영구 줄 번호가 무엇인지 모르겠습니다. 두 번째로 다른 질문은 Windows의 gVim에 대한 모든 줄에 대한 것입니다.
kenorb February

3
글쎄, post가 "영구적"을 사용한다는 것은 버퍼가 수정되고 숫자가 순수한 시각적이지 않다는 것을 나타냅니다 (귀하와 동일). 윈도우에서 gvim을 지정하는 이유는 같은 외부 유틸리티를 방지하는 것입니다 cat또는 nl수 라인을하지만 (영업 이익에 대한 자신의 의견에서 알 수 있듯이 Windows에서 일반적으로 사용할 수 없습니다 수 있습니다 awk). 최고의 두 솔루션은 순수한 Vim입니다. 마지막으로 모든 라인 대 하나의 파라는 범위 선택의 문제입니다. 분명 큰 문제는 아닙니다.
muru

답변:


36

순수한 Vim 방식으로 :

:%s/^/\=line('.').". "

설명:

:%s/^/            " the substitution will be applied to the beginning of every line
\=                " the rest of the replacement part is an expression
line('.').". "    " the expression returns the current line number concatenated with a dot and a space

참조 :help \=:help line().

교체 부분에 표현을 사용하는 것은 매우 강력하고 FWIW는 vimscript에 대한 아주 좋은 진입 점입니다.


vimrc의 키맵에이 유용한 명령을 어떻게 추가 할 수 있습니까?
cosmicraga

대체를위한 vim 도움말 주제를 얻으려면:help sub-replace-expression
akurtser

9

Vim 매크로의 좋은 점 중 하나는 재귀 할 수 있다는 것입니다 (자신을 호출 할 수 있음).

  1. 레지스터 q를 지우십시오 : qqq
  2. 첫 줄에 숫자를 추가하십시오 : ggI1.(공백을 잊지 마십시오!)
  3. 줄의 시작으로 돌아가 매크로 기록을 시작하십시오. 0qq
  4. 번호를 복사하십시오. yW
  5. 줄을 아래로 이동하고 숫자를 붙여 넣으십시오. +P
  6. 줄의 시작 부분으로 돌아가서 숫자를 늘리십시오. 0<c-a>
  7. 줄의 시작 부분으로 다시 이동하십시오 (따라서 두 배의 숫자에 도달해도 매크로가 깨지지 않습니다!) : 0
  8. 매크로를 한 번 호출하여 재귀 적으로 만드십시오. 이 시점에서 레지스터 q에는 여전히 아무것도 없으므로 아무 일도 일어나지 않습니다 @q.
  9. 매크로를 저장하십시오. q
  10. 매크로를 한 번 더 호출하고 불꽃이 날아 오는 것을보십시오! : @@

그런 다음 매크로는 파일 끝에 도달 할 때까지 계속 호출됩니다.

많은 다른 유사한 문제에 재귀 매크로 트릭을 사용할 수 있으므로 알아 두는 것이 좋습니다.

어떤 이유로 재귀 매크로를 사용하지 않으려면 1 단계와 8 단계를 생략 하고 매크로를 여러 번 실행 하기 위해 카운트 를 사용하십시오 ( 예 : 100@q매크로를 q100 번 실행 함) .


1
강력한 것들, 나는 당신의 숙달에 절합니다. 매크로는 나에게
흑마 법과 같습니다

1
@ropata, 매크로는 일련의 (대부분) 일반 모드 명령입니다.
romainl

1
@romainl 나는 그것을 일련의 키 스트로크 로 생각하는 것이 낫다고 생각합니다 .
Rich

2
@Rich, ex 명령을 포함하여 많은 것들의 순서가 될 수 있습니다.
romainl

2
@romainl 그렇기 때문에 키 스트로크라고 생각하는 것이 가장 좋습니다. 직접 입력 한 것처럼 키보드에서 입력 한 내용 (예 : ex 명령 포함)을 정확하게 재생합니다.
Rich

7

vim global 명령을 사용하여 이와 같은 작업을 수행하고 싶습니다. 이것은 줄의 시작 부분에 반복을 추가하거나 텍스트의 기호를 수정하는 데 적용됩니다. 다른 솔루션보다 복잡해 보이지만 편리 할 때 사용할 수있는 매우 유연한 패턴이며 많은 생각없이 쉽게 수정할 수 있습니다.

먼저 범위를 선택하십시오 (이 라인을 적용하려는 선). 나는 보통 마크를 사용합니다 (예 : ma첫 번째 줄과 mb두 번째 줄에서 줄 번호 나 시각적 선택을 사용할 수도 있습니다). 다음 명령의 수정 사항을 입력하십시오 (현재 사용 사례에 맞게 조정 됨).

:let i=1|'a,'bg/^/s/^/\=i.". "/|let i=i+1

해체

:let i=1

i시작 값으로 변수 를 설정합니다 . 일반적으로 목록은 1로 시작하므로 i를 1로 설정합니다.

|

바는 새로운 명령을 시작합니다

'a,'b

다음 명령의 범위를 설정합니다. mark ato mark b로 이동합니다. 목록의 첫 번째 줄과 마지막 줄에 설정됩니다.

g/^/

이것이 전역 명령입니다. 주어진 정규식에 대해 파일 (또는 범위)을 검색하고 일치하는 행에서 나머지 명령 행을 실행합니다 . "줄의 시작"을 검색하여 모든 줄을 찾습니다. 당신이 같은 텍스트를 가지고 있다면

Item some txt
other text

Item second item
whatever
Item third

그리고이 레이블을 Item다른 줄 앞에 놓고 다른 줄을 무시하고, 대신 g/Item/하거나 g/^Item/대신하십시오 (리터럴 항목 텍스트 가정)

s/^/\=i.". "/

이것은 정규 표현식을 실행하여 행의 시작 부분을로 i연결된 값으로 대체합니다 .. 일반적으로이 작업을 수행 할 수 있습니다 ( Item예 : 레이블 을 숫자로 바꿉니다).

|let i=i+1

막대가 새 명령을 시작하더라도 전역이 완료된 후가 아니라 전역 명령 내에서 실행할 두 번째 명령을 설정합니다. 결과는 i다음 행이 g에 의해 처리되기 전에 증가 합니다. 여기 또 다른 유연성이 있습니다. i의 수정은 무엇이든 가능합니다 (2 씩 증가, 피보나치 시퀀스의 다음 요소를 생성하는 함수 호출).


7

모든 줄에 숫자 추가

모든 줄에 줄 번호를 추가하는 명령 :%!nl -ba이나 :%!cat -n명령 을 사용할 수 있습니다.

Windows에서는 Cygwin / MSYS / SUA가 설치되어 있어야합니다.

선택한 줄에 숫자 추가

선택한 줄에 대해서만 숫자를 추가하려면 시각 모드 ( v및 커서) 에서 숫자를 선택한 다음 완료되면 :%!nl(빈 줄 무시) 또는 :%!cat -n(빈 줄 포함) 명령을 실행하십시오 .

서식

여분의 공백을 제거하려면 시각적 블록에서 공백을 선택하고 ( Ctrl+ v) 제거하십시오 ( x).

일부 문자를 (추가하려면 ., :, ), 숫자 후) 영상 블록 (그들을 선택 Ctrl+ v다음 (문자를 추가,) A다음 마무리, 문자를 입력합니다 Esc).


2
이것은 질문에서 주어진 것과 같은 형식을 제공하지 않습니다. 그러나 나는 솔루션의 단순성을 좋아합니다.
Karl Yngve Lervåg

@ KarlYngveLervåg 감사합니다.
kenorb

5

romainl의 답변 수정 :

:%s/^\(\d\+\. \)\?/\=line('.').". "

이것은 행 번호를 추가 할뿐만 아니라 이미 존재하는 종료 행 번호를 대체 합니다. 중간에 줄을 삽입하면 예상대로 모든 번호가 다시 매겨집니다.

이것은 임의의 숫자를 대체하고 뒤에을 붙여서 작동합니다. 그리고 줄의 시작 부분에 새로운 숫자가있는 공백. 이미이 패턴으로 시작하는 줄이 있으면 분명히 중단되므로 생각과 함께 사용하십시오.

추가 된 부분 :

  • ^ -줄의 시작
  • \( -새로운 부분 군 시작
  • \d\+ -한 번 이상 숫자 일치
  • \. -점 ( .)과 공백을 일치 시킵니다.
  • \) -하위 그룹 종료
  • \? -이 줄에 번호가없는 것처럼 이전처럼 작동하도록 그룹을 선택적으로 만듭니다.

보너스 힌트 : 줄 번호
제거 하려면 repalce 부분을 비운 상태에서 동일한 패턴을 사용할 수 있습니다.

:%s/^\(\d\+\. \)\?//

5
I1. <esc>^qqyWjP^<C-a>q

이것은 처음 두 줄 @q에 번호를 매기 며을 누르면 다음 줄에 번호를 매길 수 있습니다 (또는 18@q총 20 줄을 번호를 매기려면 예를 입력하십시오 ).

설명:

I1. <esc>  Number the first line
hqq        Go back to the start of the line and start recording a macro
yWjP       Copy the line number to the next line
^<C-a>     Increment the next line's line number
q          Finish recording

이것의 장점은 외부 명령이 필요하지 않기 때문에 Windows에서 Vim을 사용하는 경우에 유용합니다.


입력 후 1. <esc>h첫 번째 열이 아닌 두 번째 열에 있습니다. 나는 대체 할 h함께 0내가 솔루션은 매우 잘한다고 생각 후를.
Karl Yngve Lervåg

@ KarlYngveLervåg Whoops, 그건 오타였습니다. 고마워요
Doorknob

문제 없어. 그러나 여전히 설명을 업데이트하지 않았습니다. 또한 : 많은 키보드에서 ^와 같은 입력 조합을 허용하기 위해 두 번째 문자를 기다립니다 ^a -> â. 나는 여전히 최선의 해결책에 동의하지만 이것도 언급해야한다고 생각합니다.
Karl Yngve Lervåg

3

선택한 답변이 최고라고 생각하지만 다양성에 따라 외부 프로그램을 사용하는 대안을 제공 할 것입니다.

:%!cat -n

이렇게하면 %외부 프로그램을 통해 전체 버퍼 (로 표시됨 ) 가 필터링됩니다 cat. 여기서 -n플래그는 각 입력 행 앞에 줄 번호가 붙습니다.

물론 이것은 cat설치 해야합니다 . 이는 아마도 모든 유닉스 계열 시스템에 해당됩니다.

:help :range!외부 프로그램을 통한 필터링에 대한 자세한 내용을 확인하십시오 .


1
asker가 Windows에서 gVim을 사용하고 있다는 것을 알고 있으므로이 솔루션은 작동하지 않을 것입니다. 그러나 나는 그것이 여전히 다른 사람들이 배울 수있는 기회를 제공한다고 생각합니다.
tommcdo

msysgitPATH에 설치 하고 추가 한 경우 (IIRC는 설치 옵션)이 솔루션은 Windows에서도 작동합니다.
Martin Tournoij

4
cat -nPOSIX는 아니지만 nl더 나은 옵션 일 수 있습니다.
muru

2

약간의 해킹 해결책은 다음과 같습니다 (<와> 사이에 쓰여진 모든 것은 Ctrl+ 를 누른 후에 삽입됩니다 v) :

:%normal :redir @"<Enter>:-=<Enter>:redir END<Enter>I<C-R>".<Tab><Esc>kdd

해체

:%normal {commands}

범위로 지정된 각 줄 (이 경우 모든 줄)에서 일반 모드 명령을 실행합니다.

:redir @"

ex 명령으로 작성된 모든 출력을 명명되지 않은 버퍼로 리디렉션합니다.

:.=

현재 줄 번호를 출력하는 ex 명령입니다 (불행히도 이전 줄 바꿈이 있음)

:redir END

명명되지 않은 버퍼로의 리디렉션을 중지합니다

I<C-R>".<Tab><Esc>

이름이없는 버퍼의 내용을로 삽입합니다. 각 줄의 앞쪽에 탭을 삽입하고 삽입 모드를 종료합니다.

kdd

:. = 명령의 결과 인 한 줄 위로 가서 줄 바꿈을 제거합니다.

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