The easiest way would be to read the file in as a single string and then split it across your separator:
with open('myFileName') as myFile:
text = myFile.read()
result = text.split(separator) # use your \-1 (whatever that means) here
In case your file is very large, holding the complete contents in memory as a single string for using .split() is maybe not desirable (and then holding the complete contents in the list after the split is probably also not desirable). Then you could read it in chunks:
def each_chunk(stream, separator):
buffer = ''
while True: # until EOF
chunk = stream.read(CHUNK_SIZE) # I propose 4096 or so
if not chunk: # EOF?
yield buffer
break
buffer += chunk
while True: # until no separator is found
try:
part, buffer = buffer.split(separator, 1)
except ValueError:
break
else:
yield part
with open('myFileName') as myFile:
for chunk in each_chunk(myFile, separator='\\-1\n'):
print(chunk) # not holding in memory, but printing chunk by chunk
Answer from Alfe on Stack OverflowThe easiest way would be to read the file in as a single string and then split it across your separator:
with open('myFileName') as myFile:
text = myFile.read()
result = text.split(separator) # use your \-1 (whatever that means) here
In case your file is very large, holding the complete contents in memory as a single string for using .split() is maybe not desirable (and then holding the complete contents in the list after the split is probably also not desirable). Then you could read it in chunks:
def each_chunk(stream, separator):
buffer = ''
while True: # until EOF
chunk = stream.read(CHUNK_SIZE) # I propose 4096 or so
if not chunk: # EOF?
yield buffer
break
buffer += chunk
while True: # until no separator is found
try:
part, buffer = buffer.split(separator, 1)
except ValueError:
break
else:
yield part
with open('myFileName') as myFile:
for chunk in each_chunk(myFile, separator='\\-1\n'):
print(chunk) # not holding in memory, but printing chunk by chunk
I used "*" instead of "-1", I'll let you make the appropriate changes.
s = '1.Hai\n2.Bye*3.Hello\n4.OAPd*'
temp = ''
results = []
for char in s:
if char is '*':
results.append(temp)
temp = []
else:
temp += char
if len(temp) > 0:
results.append(temp)
python 3.x - Reading txt file till certain point and then create new txt file out of existing file - Software Engineering Stack Exchange
Analyzing string input until it reaches a certain letter on Python - Stack Overflow
python - Read file up to a character - Stack Overflow
text - Read Up Until a Point Python - Stack Overflow
I have this code:
with open(inputfile, 'r') as infile:
for line in infile:
if line.startswith(">"):
print line
# keep printing until next ">" encountered; stop at that point
# and move on to next line that starts with ">"...But I don't know how to do that last part...keep printing lines in the file until I hit the next ">", at which point I need it to stop printing, find the next line that starts with ">", then start printing again.
I've searched like every google link for this. It has been asked a lot, but nowhere is there an explanation understand. Usually it's also some variation, such as print from the start until match, but I know how to do that. I need to print from match to match...
I think I can do this with enumerate() a list, and a while loop, but it requires I read the file into memory, which I don't want to do considering the files I need to work on are a few GB each and contain a few million lines, so I don't want to read the entire thing into a list...
The real problem I am having is how to access the "next line" after the line that contains ">"? next(infile) works, but only for the immediate next line. What if I need the next 2 or 3 lines? I tried the following inside the "if line.startswith" part:
line = next(infile)
while not line.startswith(">"):
print line
line = next(infile)But that doesn't work...(not entirely sure why, I assume next() can only take the immediate next line).
Anyone? Is there no default python function (that I can't find) that does this?
files are iterators (unlike lists) so you can just make a second for loop:
with open(inputfile, 'r') as infile:
for line in infile:
if line.startswith(">"):
print line, # comma on the end prevents the double spacing from printing a file line
for line in infile:
print line,
if line.startswith(">"):
break # stop this inner for loop; outer loop picks up on the next line
Edit: I get the feeling I don't understand your problem. Can you show some example data and what you want out?
An easy way to do it would be something like this:
should_print = False
with open(inputfile, 'r') as infile:
for line in infile:
if line.startswith(">"):
# should_print becomes True if was False and becomes False if was True
should_print = not should_print
if should_print:
print(line)
The built-in str.partition() method will do this for you. Unlike str.split() it won't bother to cut the rest of the str into different strs.
text = raw_input("Type something:")
left_text = text.partition("!")[0]
Explanation
str.partition() returns a 3-tuple containing the beginning, separator, and end of the string. The [0] gets the first item which is all you want in this case. Eg.:
"wolfdo65gtornado!salmontiger223".partition("!")
returns
('wolfdo65gtornado', '!', 'salmontiger223')
>>> s = "wolfdo65gtornado!salmontiger223"
>>> s.split('!')[0]
'wolfdo65gtornado'
>>> s = "wolfdo65gtornadosalmontiger223"
>>> s.split('!')[0]
'wolfdo65gtornadosalmontiger223'
if it doesnt encounter a "!" character, it will just grab the entire text though. if you would like to output an error if it doesn't match any "!" you can just do like this:
s = "something!something"
if "!" in s:
print "there is a '!' character in the context"
else:
print "blah, you aren't using it right :("
If there aren't going to be newlines in the file to start with, transform the file before piping it into your Python script, e.g.:
tr '~' '\n' < source.txt | my-script.py
Then use readline(), readlines(), or for line in file_object: as appropriate.
This is still far from optimal, but it would be a pure-Python implementation of a very simple buffer:
def my_open(filename, char):
with open(filename) as f:
old_fb=""
for file_buffer in iter(lambda: f.read(1024), ''):
if old_fb:
file_buffer = old_fb + file_buffer
pos = file_buffer.find(char)
while pos != -1 and file_buffer:
yield file_buffer[:pos]
file_buffer = file_buffer[pos+1:]
pos = file_buffer.find(char)
old_fb = file_buffer
yield old_fb
# Usage:
for line in my_open("weirdfile", "~"):
print(line)
Read line by line. Use #main as a flag to start processing. Use #extra as a flag to stop processing.
start = '#main'
end = '#extra'
numbers = []
file_handler = open('read_up_to_a_point.txt')
started = False
for line in file_handler:
if end in line:
started = False
if started:
numbers.append(line.strip())
if start in line:
started = True
file_handler.close()
print numbers
sample output
python read_up_to_a_point.py ['60258960', '33031674', '72302403']
You're pretty close, as you are. You just need to modify your list slice to chop off the last two lines in the file along with the first two. readlines will naturally return a list where each item is one line from the file. However, it will also have the 'newline' character at the end of each string, so you may need to filter that out.
with open("myfile.txt") as myfile:
# Get only numbers
read = myfile.readlines()[2:-2]
# Remove newlines
read = [number.strip() for number in read]
print read
This is pretty straight forward, you can terminate a loop early with a break statement.
filename = 'somefile.txt'
with open(filename, 'r') as input:
for line in input:
if 'indicator' in line:
break
Using with creates a compound statement that ensures that upon entering and leaving the scope of the with statement __enter__() and __exit__() will be called respectively. For the purpose of file reading this will prevent any dangling filehandles.
The break statement tells the loop to terminate immediately.
Use iter()'s sentinel parameter:
with open('test.txt') as f:
for line in iter(lambda: f.readline().rstrip(), 'SPECIFIC LINE'):
print(line)
output:
file start here..
some data...
Reference: https://docs.python.org/2/library/functions.html#iter
useful = []
with open ("Report.txt", "r") as myfile:
for line in myfile:
if "===" in line:
break
for line in myfile:
useful.append(line)
a_string = "".join(useful)
I would however prefer to hide it away in a generator, like this:
def report_iterator():
with open ("Report.txt", "r") as myfile:
for line in myfile:
if "===" in line:
break
for line in myfile:
yield line
for line in report_iterator():
# do stuff with line
All the filtering and nitpicking is done in the generator function, and you can separate the logic of "filtering input" from the logic of "working with the input".
You could read line by line, and by default not store the lines. When you get the line starting with '==', then all lines you read until you read the second '==' line you store in your string or list.
I have a text file where I want to do this:
-
read text into a string
-
if I hit a special character do something accordingly
-
if I hit an * do X with the string
-
if I hit a ~ do Y with the string
-
-
continue reading from where I left off
-
repeat until EOF
I'm currently using ifstream read, but that just reads until a number of characters, which I can't always know. I know there's getchar, but that reads from input and I want to read from a file. Can anyone help me out?