여기에는 텍스트 파일을 제자리에서 수정하여 지정된 줄을 동일한 길이의 줄로 바꾸는 기능이 있습니다.
이 데모에서는 대체 문자로 #
을 사용하여 어떤 일이 일어나는지 쉽게 확인합니다. 대신 간단한 공간 (chr(32)
) 또는 ASCII DEL 문자 (chr(127)
== \x7f
)를 사용할 수 있습니다. DEL을 사용하면 파일의 "적절한"행에 문자가 나타나지 않기 때문에 모든 "지워진"행을 빠르게 삭제하는 것이 더 쉽습니다.
첫째, 여기에이 코드를 테스트 할 수있는 작은 텍스트 파일이 있습니다.
qdata
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
여기에 코드입니다. 1에서 시작하는 줄 번호 매기기를 사용합니다. 여기
def erase_line(fname, line_num):
''' In-place replacement of line `line_num` in file `fname` with
a line of DEL chars of the same length, retaining the newline.
'''
DEL = '#'
with open(fname, 'r+') as f:
for i in range(line_num - 1):
f.readline()
start = f.tell()
line = f.readline()
line = DEL * (len(line) - 1) + '\n'
f.seek(start)
f.write(line)
erase_line('qdata', 3)
이
qdata의 수정 된 버전입니다 :
1 one
2 two
#######
4 four
5 five
6 six
7 seven
8 eight
9 nine
는 다양한 길이의 라인을 처리해야하기 때문에
이
erase_line
이 원하는 하나를 찾을 때까지 모든 라인을 읽을 수있다하지만, 그것은 단지 그 라인을 다시 쓰고, 다른 라인들은 수정하지 않기 때문에, 그것은 꽤 빠르다. 줄의 길이가 고정 된 경우
.skip
을 사용하여 원하는 줄로 바로 이동할 수 있습니다.
다음은 완전히 DEL 문자로 구성된 모든 행을 제거하고 결과를 새 파일에 쓰는 기능입니다.
def compact(oldname, newname):
''' Copy file `oldname` to `newname`, removing lines that
consist entirely of the DEL char, apart from the '\n'
'''
DEL = '#'
with open(oldname, 'r') as fin, open(newname, 'w') as fout:
for line in fin:
if not line.lstrip(DEL) == '\n':
fout.write(line)
compact('qdata', 'qdata.new')
qdata.new
1 one
2 two
4 four
5 five
6 six
7 seven
8 eight
9 nine
마지막으로, 여기에 당신이 (8 진수 \177
입니다) 실제 DEL 문자를 사용하는 가정의 성형 작업을 수행하는 유닉스/리눅스 파이프 라인입니다. 파이썬 버전보다 빠르다.
tr -d '\177' <qdata | awk '!/^$/' >qdata.new
특정 줄을 공백 문자로 바꾸면 충분합니까? 그렇지 않으면 해당 행 뒤의 모든 바이트를 거꾸로 변환해야합니다. – fuglede
@fuglede 공백 문자로 충분할 것 같아요. 그러나 이제는 동작 이후에 고정 바이트 길이가 필요하다는 것을 알게되었습니다. C 에서처럼. 그러나 각 줄의 길이를 확인하고 충분한 수의 공백으로 바꿀 수 있습니다. 나는 아직도 파이썬에서 그것을 성취하는 방법을 모른다. – Rockybilly
fuglede가 말했듯이, 원하지 않는 바이트를 공백 문자로 대체 할 수 있습니다 (예 : 공백 문자 (ASCII 코드 0x20)). 전통적으로 이러한 목적으로 [DEL 문자] (https://en.wikipedia.org/wiki/Delete_character) (ASCII 코드 0x7f)가 사용되었습니다. –