파일에서 특정 줄 (줄 번호 사용)을 어떻게 제거합니까?


27

파일에서 제거하려는 특정 줄이 있습니다. 20-37 행과 45 행이라고합시다. 해당 행의 내용을 지정하지 않고 어떻게해야합니까?


파일이 얼마나 큽니까? 메모리에로드 할 수 있습니까?
Faheem Mitha

몇 킬로바이트.
tshepang

답변:


29

로 다음과 sed같이하십시오.

sed '20,37d; 45d' < input.txt > output.txt

이 작업을 제대로 수행하려면 다음을 수행하십시오.

sed --in-place '20,37d; 45d' file.txt

제자리에서 수행하는 방법이 있습니까?
tshepang

나는 -i 파일을 나오지 제안
enzotib을

1
@Tshepang : 사용 ed, 또는 GNU는 나오지 -i하거나 sponge, 또는 큰 파일 방법 .
Gilles 'SO- 악마 중지'

3
나는 종종 'sed'를 언급 할 때 오해의 소지가있는 용어 대해 궁금해 했기 때문에 'man sed'에서 찾았습니다 : --in-place [= SUFFIX] This option specifies that files are to be edited in-place. GNU sed '임시 파일을 작성 하여이 작업을 수행합니다 표준 출력이 아닌이 파일로 출력을 보냅니다 .` ... 다른 'sed'에 대해서는 모르지만 스트림 편집기로 "제자리"를 업데이트하는 물류는 "계산"하지 않습니다. :)
Peter.O

2
대부분의 "in-place"방법은 제 경험상 임시 파일을 사용합니다.
Faheem Mitha

5

파일이 메모리에 편안하게 들어가면을 사용할 수도 있습니다 ed.
명령은 sed가지 눈에 띄는 차이점 을 제외하고는 위 의 명령과 매우 유사합니다. 줄 번호 / 범위 목록을 내림차순으로 전달해야합니다 (가장 높은 행 번호 / 범위에서 가장 낮은 행까지). 로 줄을 삭제 / 삽입 / 분할 / 조인 할 때 ed각 하위 명령 후에 텍스트 버퍼가 업데이트되므로 일부 줄을 삭제하면 다음 줄의 나머지 부분이 더 이상 버퍼에서 동일한 위치에 있지 않기 때문입니다. 다음 부속 명령이 실행됩니다. 따라서 거꾸로 시작해야합니다 1 .
전체 편집 :

ed -s in_file <<IN
45d
20,37d
w
q
IN

또는

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

또는

printf '%s\n' 45d 20,37d w q | ed -s in_file

교체 w와 의식 ,p대신 파일에 쓰기의 결과 출력을 인쇄하려면 RINT. 원래 파일을 그대로 유지하고 다른 파일에 쓰려면 새 파일 이름을 write 부속 명령에 전달할 수 있습니다 .

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1delete 다음에 새로운 줄 번호를 기꺼이 계산하지 않는 한 ,이 특별한 경우에는 아주 사소합니다 (20-37 줄, 18 줄, 45 줄이 27 줄이 됨). 다음을 실행할 수 있습니다.

ed -s in_file <<IN
20,37d
27d
w
q
IN

그러나 여러 줄 번호 / 범위를 삭제해야하는 경우 뒤로 작업하는 것은 쉬운 일이 아닙니다.


는 IS q명령은 마지막에 유용? 어느 쪽이든 나가는 것 같아요.
Tom Fenech

@TomFenech-모든 구현이 어느 쪽이든 종료되는 것은 아닙니다 (대부분의 경우 ... 더 이상 논의 된 스레드를 찾을 수 없습니다 ...)
don_crissti

1

메모리로 읽어서 수정 한 다음 다시 쓰십시오. 당신은 같은 것을 할 수 있습니다

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

5 줄 파일로 테스트했습니다. 크레딧 http://pleac.sourceforge.net/pleac_python/fileaccess.html는 "임시 파일없이 장소에서 파일 수정"절을 참조하십시오. 참조 https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python

몇 가지 참고 사항 :

  1. 위와 같이 먼저 파일을 잘라낸 다음 쓰기보다는 잘라 내기보다는 파일에 쓸 수 있습니다. 그러나 파이썬 플래그를 읽은 다음 잘린 쓰기를 수행하는 것을 알 수 없습니다. 그러나 문서가 명확하지 않기 때문에 뭔가 빠졌을 수 있습니다. 어느 날로

  2. 때때로 파이썬 문서는 정말 짜증납니다. http://docs.python.org/library/functions.html#open을 참조 하십시오

    'r +', 'w +'및 'a +'모드는 업데이트 할 파일을 엽니 다 ( 'w +'는 파일을 자릅니다).

    이것이 당신에게 어떤 의미입니까? "업데이트를 위해 열린"도대체 무엇입니까?

  3. 스트림 편집기와 같은 유닉스와 달리 파이썬 에서이 작업을 수행하는 것이 더 좋은지 모르겠습니다. 좀 더 휴대하기는 쉽지만, 휴대용 sed가 어떤지 모르겠습니다. 방금 고전 유닉스 도구를 사용하는 것보다 낮은 수준의 프로그래밍에 더 익숙하기 때문에 원하는대로 정확하게 작성하면 좋지만 일반적으로 유연성이 떨어집니다.

  4. 이 방법 (파일을 메모리에서 조작)은 메모리를 디스크 공간으로 교환합니다. 최대 수백 Mb의 파일에 대해 몇 Gb의 메모리가있는 시스템에서는 정상적으로 작동합니다. 파이썬은 문자열을 매우 효율적으로 처리하지 않으므로 C / C ++로 전환하면 성능이 약간 향상되고 메모리 사용량이 크게 줄어 듭니다.


0

Ex 모드에서 Vim을 사용할 수 있습니다 :

ex -sc '20,37d|45d|x' file
  1. d 지우다

  2. x 저장하고 닫습니다

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