IT story

특정 줄만 읽기

hot-time 2020. 5. 11. 08:09
반응형

특정 줄만 읽기


파일을 읽기 위해 for 루프를 사용하고 있지만 줄 # 26 및 # 30과 같은 특정 줄만 읽으려고합니다. 이를 달성하기위한 내장 기능이 있습니까?

감사


읽을 파일이 크고 메모리에서 전체 파일을 한 번에 읽고 싶지 않은 경우 :

fp = open("file")
for i, line in enumerate(fp):
    if i == 25:
        # 26th line
    elif i == 29:
        # 30th line
    elif i > 29:
        break
fp.close()

참고 i == n-1에 대한 n라인 째.


Python 2.6 이상에서 :

with open("file") as fp:
    for i, line in enumerate(fp):
        if i == 25:
            # 26th line
        elif i == 29:
            # 30th line
        elif i > 29:
            break

빠른 답변 :

f=open('filename')
lines=f.readlines()
print lines[25]
print lines[29]

또는:

lines=[25, 29]
i=0
f=open('filename')
for line in f:
    if i in lines:
        print i
    i+=1

linecache ( "python : 거대한 텍스트 파일에서 특정 행으로 이동하는 방법?" , 이전 stackoverflow.com 질문) 를 추출하는 더 우아한 솔루션이 있습니다.

위에 링크 된 파이썬 문서 인용하기 :

>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'

4원하는 줄 번호로 변경하면 됩니다. 카운트가 0부터 시작하므로 4는 다섯 번째 줄을 가져옵니다.

파일이 매우 커서 메모리로 읽을 때 문제가 발생하면 @Alok의 조언 을 받아 enumerate ()를 사용 하는 것이 좋습니다 .

결론적으로:

  • 작은 파일을위한 빠른 솔루션으로 fileobject.readlines()또는 사용하십시오 for line in fileobject.
  • linecache더 많은 파일을 읽는 데 매우 빠른 더 우아한 솔루션을 사용 하면 반복적으로 가능합니다.
  • @Alok의 조언을enumerate() 받아 용량이 크거나 메모리에 맞지 않는 파일에 사용 하십시오. 파일을 순차적으로 읽으므로이 방법을 사용하면 속도가 느려질 수 있습니다.

빠르고 컴팩트 한 접근 방식은 다음과 같습니다.

def picklines(thefile, whatlines):
  return [x for i, x in enumerate(thefile) if i in whatlines]

이것은 열려있는 파일과 같은 객체 thefile(디스크 파일에서 또는 소켓이나 다른 파일과 같은 스트림을 통해 열어야하는지 여부를 호출자에게 맡김)와 0부터 시작하는 라인 인덱스 집합을 받아들이고 whatlines, 메모리 풋 프린트가 낮고 속도가 적당합니다. 리턴되는 라인 수가 많으면 생성기를 선호 할 수 있습니다.

def yieldlines(thefile, whatlines):
  return (x for i, x in enumerate(thefile) if i in whatlines)

이것은 기본적으로 루핑에만 적합합니다-유일한 차이점은 return명령문 에서 사각형 괄호 대신 둥근 괄호를 사용하여 목록 이해와 생성기 표현식을 만드는 것입니다.

또한 노트 '선'과의 언급에도 불구하고 "파일"이 기능은 많은 것을, 훨씬 더 일반적으로는 - 그들은 작동합니다 모든 항목의 목록 (또는 발전기를) 반환, 그것을 열린 파일 또는 어떤 다른 일, 반복 가능한 점진적인 항목 번호를 기준으로합니다. 따라서 더 적절한 일반 이름을 사용하는 것이 좋습니다 .-).


다른 솔루션을 제공하기 위해 :

import linecache
linecache.getline('Sample.txt', Number_of_Line)

나는 이것이 쉽고 빠르기를 바랍니다 :)


7 행을 원한다면

line = open ( "file.txt", "r"). readlines () [7]

완전성을 위해 여기에 또 하나의 옵션이 있습니다.

파이썬 문서 의 정의부터 시작해 봅시다 .

슬라이스 일반적으로 시퀀스의 일부를 포함하는 객체입니다. variable_name [1 : 3 : 5]와 같이 몇 개가 주어지면 숫자 사이에 콜론이있는 첨자 표기법 []을 사용하여 슬라이스를 만듭니다. 대괄호 (첨자) 표기법은 슬라이스 객체를 내부적으로 (또는 이전 버전 인 __getslice __ () 및 __setslice __ ()) 사용합니다.

슬라이스 표기법이 일반적으로 반복자에 직접 적용되지는 않지만 itertools패키지에는 대체 기능이 포함되어 있습니다.

from itertools import islice

# print the 100th line
with open('the_file') as lines:
    for line in islice(lines, 99, 100):
        print line

# print each third line until 100
with open('the_file') as lines:
    for line in islice(lines, 0, 100, 3):
        print line

함수의 또 다른 장점은 반복자가 끝날 때까지 반복자를 읽지 않는다는 것입니다. 따라서 더 복잡한 작업을 수행 할 수 있습니다.

with open('the_file') as lines:
    # print the first 100 lines
    for line in islice(lines, 100):
        print line

    # then skip the next 5
    for line in islice(lines, 5):
        pass

    # print the rest
    for line in lines:
        print line

그리고 원래 질문에 대답하기 위해 :

# how to read lines #26 and #30
In [365]: list(islice(xrange(1,100), 25, 30, 4))
Out[365]: [26, 30]

파일을 읽는 것은 엄청나게 빠릅니다. 100MB 파일을 읽는 데 0.1 초 미만이 소요됩니다 ( Python으로 파일 읽기 및 쓰기 참조 ). 따라서 당신은 그것을 완전히 읽고 한 줄로 작업해야합니다.

대부분의 대답은 잘못된 것이 아니라 나쁜 스타일입니다. 파일을 with다시 닫을 수 있도록 항상 파일을 열어야합니다.

따라서 다음과 같이해야합니다.

with open("path/to/file.txt") as f:
    lines = f.readlines()
print(lines[26])  # or whatever you want to do with this line
print(lines[30])  # or whatever you want to do with this line

거대한 파일

파일이 많고 메모리 소비가 중요한 경우 파일을 한 줄씩 처리 할 수 ​​있습니다.

with open("path/to/file.txt") as f:
    for i, line in enumerate(f):
        pass  # process line i

이들 중 일부는 사랑 스럽지만 훨씬 간단하게 수행 할 수 있습니다.

start = 0 # some starting index
end = 5000 # some ending index
filename = 'test.txt' # some file we want to use

with open(filename) as fh:
    data = fin.readlines()[start:end]

print(data)

그것은 단순히 목록 슬라이싱을 사용하고 전체 파일을로드하지만 대부분의 시스템은 메모리 사용을 적절하게 최소화하고 위에 주어진 대부분의 방법보다 빠르며 10G + 데이터 파일에서 작동합니다. 행운을 빕니다!


You can do a seek() call which positions your read head to a specified byte within the file. This won't help you unless you know exactly how many bytes (characters) are written in the file before the line you want to read. Perhaps your file is strictly formatted (each line is X number of bytes?) or, you could count the number of characters yourself (remember to include invisible characters like line breaks) if you really want the speed boost.

Otherwise, you do have to read every line prior to the line you desire, as per one of the many solutions already proposed here.


How about this:

>>> with open('a', 'r') as fin: lines = fin.readlines()
>>> for i, line in enumerate(lines):
      if i > 30: break
      if i == 26: dox()
      if i == 30: doy()

If you don't mind importing then fileinput does exactly what you need (this is you can read the line number of the current line)


def getitems(iterable, items):
  items = list(items) # get a list from any iterable and make our own copy
                      # since we modify it
  if items:
    items.sort()
    for n, v in enumerate(iterable):
      if n == items[0]:
        yield v
        items.pop(0)
        if not items:
          break

print list(getitems(open("/usr/share/dict/words"), [25, 29]))
# ['Abelson\n', 'Abernathy\n']
# note that index 25 is the 26th item

I prefer this approach because it's more general-purpose, i.e. you can use it on a file, on the result of f.readlines(), on a StringIO object, whatever:

def read_specific_lines(file, lines_to_read):
   """file is any iterable; lines_to_read is an iterable containing int values"""
   lines = set(lines_to_read)
   last = max(lines)
   for n, line in enumerate(file):
      if n + 1 in lines:
          yield line
      if n + 1 > last:
          return

>>> with open(r'c:\temp\words.txt') as f:
        [s for s in read_specific_lines(f, [1, 2, 3, 1000])]
['A\n', 'a\n', 'aa\n', 'accordant\n']

Here's my little 2 cents, for what it's worth ;)

def indexLines(filename, lines=[2,4,6,8,10,12,3,5,7,1]):
    fp   = open(filename, "r")
    src  = fp.readlines()
    data = [(index, line) for index, line in enumerate(src) if index in lines]
    fp.close()
    return data


# Usage below
filename = "C:\\Your\\Path\\And\\Filename.txt"
for line in indexLines(filename): # using default list, specify your own list of lines otherwise
    print "Line: %s\nData: %s\n" % (line[0], line[1])

A better and minor change for Alok Singhal's answer

fp = open("file")
for i, line in enumerate(fp,1):
    if i == 26:
        # 26th line
    elif i == 30:
        # 30th line
    elif i > 30:
        break
fp.close()

File objects have a .readlines() method which will give you a list of the contents of the file, one line per list item. After that, you can just use normal list slicing techniques.

http://docs.python.org/library/stdtypes.html#file.readlines


@OP, you can use enumerate

for n,line in enumerate(open("file")):
    if n+1 in [26,30]: # or n in [25,29] 
       print line.rstrip()

file = '/path/to/file_to_be_read.txt'
with open(file) as f:
    print f.readlines()[26]
    print f.readlines()[30]

Using the with statement, this opens the file, prints lines 26 and 30, then closes the file. Simple!


You can do this very simply with this syntax that someone already mentioned, but it's by far the easiest way to do it:

inputFile = open("lineNumbers.txt", "r")
lines = inputFile.readlines()
print (lines[0])
print (lines[2])

To print line# 3,

line_number = 3

with open(filename,"r") as file:
current_line = 1
for line in file:
    if current_line == line_number:
        print(file.readline())
        break
    current_line += 1

Original author: Frank Hofmann


If your large text file file is strictly well-structured (meaning every line has the same length l), you could use for n-th line

with open(file) as f:
    f.seek(n*l)
    line = f.readline()  # please notice the s at the end!
    last_pos = f.tell()

Disclaimer This does only work for files with the same length!


Fairly quick and to the point.

To print certain lines in a text file. Create a "lines2print" list and then just print when the enumeration is "in" the lines2print list. To get rid of extra '\n' use line.strip() or line.strip('\n'). I just like "list comprehension" and try to use when I can. I like the "with" method to read text files in order to prevent leaving a file open for any reason.

lines2print = [26,30] # can be a big list and order doesn't matter.

with open("filepath", 'r') as fp:
    [print(x.strip()) for ei,x in enumerate(fp) if ei in lines2print]

or if list is small just type in list as a list into the comprehension.

with open("filepath", 'r') as fp:
    [print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]

To print desired line. To print line above/below required line.

def dline(file,no,add_sub=0):
    tf=open(file)
    for sno,line in enumerate(tf):
        if sno==no-1+add_sub:
         print(line)
    tf.close()

execute---->dline("D:\dummy.txt",6) i.e dline("file path", line_number, if you want upper line of the searched line give 1 for lower -1 this is optional default value will be taken 0)


f = open(filename, 'r')
totalLines = len(f.readlines())
f.close()
f = open(filename, 'r')

lineno = 1
while lineno < totalLines:
    line = f.readline()

    if lineno == 26:
        doLine26Commmand(line)

    elif lineno == 30:
        doLine30Commmand(line)

    lineno += 1
f.close()

I think this would work

 open_file1 = open("E:\\test.txt",'r')
 read_it1 = open_file1.read()
 myline1 = []
 for line1 in read_it1.splitlines():
 myline1.append(line1)
 print myline1[0]

참고URL : https://stackoverflow.com/questions/2081836/reading-specific-lines-only

반응형