find lines from a file with the content of another file Python - python

So.. here's what i'm trying to do..
For each line in the datafile, check if the other file contains this string.
I tried some stuff from other posts, but non of them were any good.
The code below says it didnt find any of the string it was looking for, even while they were present somewhere in the file.
def search():
file1= open('/home/example/file1.txt', 'r')
datafile= open('/home/user/datafile.txt', 'r')
for line in datafile:
if line in file1:
print '%s found' % line
else:
print '%s not found' % line
search()

Assuming the content of the first file is not extremely large, you can read the entire file as string and then check using string containment:
def search():
file1_content = open('/home/example/file1.txt').read()
datafile = open('/home/user/datafile.txt')
for line in datafile:
if line in file1_content:
print '%s found' % line
else:
print '%s not found' % line
Note that the default mode for open is 'r', so you really don't need to pass that parameter if you're reading in text mode.

You can read the file into a set and then check for inclusion in the second file. set's are typically faster at checking inclusion that lists.
def search():
file1 = set(open('/home/example/file1.txt'))
datafile= open('/home/user/datafile.txt', 'r')
for line in datafile:
if line in file1:
print '%s found' % line
else:
print '%s not found' % line
You could also use set operations to extract, for instance, all lines not in the first file:
set(open('/home/user/datafile.txt', 'r')) - set(open('/home/example/file1.txt'))

Related

Writing a line in a file when finding a keyword

I am trying to make a function which writes a line when it finds some text inside a file.
Example: it finds "hello" in a .txt file so then writes "Hi!" in the following line. There is something else, i want it to write "Hi!" not the first time it finds "hello" but the second.
Here is what i have been trying, but i don't know if the idea is right. Any help?
def line_replace(namefilein):
print namefilein
filein=open(namefilein, "rw")
tag="intro"
filein.read()
for line in filein:
if tag=="second" or tag=="coord":
try:
filein.write("\n\n %s" %(text-to-be-added))
print line
except:
if tag=="coord":
tag="end"
else:
tag="coord"
if " text-to-find" in line:
if tag=="intro":
tag="first"
elif tag=="first":
tag="second"
filein.close()
You can use this code:
def line_replace(namefilein):
new_content = ''
first_time = False
with open(namefilein, 'r') as f:
for line in f:
new_content += line
if 'hello' in line:
if first_time:
new_content += 'Hi!' + '\n'
else:
first_time = True
with open(namefilein, 'w') as f:
f.write(new_content)
Look that I am using the with statement that in Python is a context manager, so it means, in this case, when the block of code has executed, then the file will be closed automatically.
Let's supposed you have a file my_file.txt which contents is:
hello
friend
this
is
hello
And let's say your file is in the same directory than the python file that has your code, so calling:
line_replace('my_file.txt')
will produce the following output:
hello
friend
hello
Hi!
is

Reading a textfile into a String

I'm just starting to learn python and have a textfile that looks like this:
Hello
World
Hello
World
And I want to add the numbers '55' to the beggining and end of every string that starts with 'hello'
The numbers '66' to the beggining and every of every string that starts with 'World'
etc
So my final file should look like this:
55Hello55
66World66
55Hello55
66World66
I'm reading the file in all at once, storing it in a string, and then trying to append accordingly
fp = open("test.txt","r")
strHolder = fp.read()
print(strHolder)
if 'Hello' in strHolder:
strHolder = '55' + strHolder + '55'
if 'World' in strHolder:
strHolder = '66' + strHolder + '66'
print(strHolder)
fp.close()
However, my string values '55' and '66' are always being added to the front of the file and end of the file, not the front of a certain string and to the end of the string, where I get this output of the string:
6655Hello
World
Hello
World
5566
Any help would be much appreciated.
You are reading the whole file at once with .read().
You can read it line by line in a for loop.
new_file = []
fp = open("test.txt", "r")
for line in fp:
line = line.rstrip("\n") # The string ends in a newline
# str.rstrip("\n") removes newlines at the end
if "Hello" in line:
line = "55" + line + "55"
if "World" in line:
line = "66" + line + "66"
new_file.append(line)
fp.close()
new_file = "\n".join(new_file)
print(new_file)
You could do it all at once, by reading the whole file and splitting by "\n" (newline)
new_file = []
fp = open("text.txt")
fp_read = fp.read()
fp.close()
for line in fp_read.split("\n"):
if "Hello" # ...
but this would load the whole file into memory at once, while the for loop only loads line by line (So this may not work for larger files).
The behaviour of this is that if the line has "Hello" in it, it will get "55" before and after it (even if the line is " sieohfoiHellosdf ") and the same for "World", and if it has both "Hello" and "World" (e.g. "Hello, World!" or "asdifhoasdfhHellosdjfhsodWorldosadh") it will get "6655" before and after it.
Just as a side note: You should use with to open a file as it makes sure that the file is closed later.
new_file = []
with open("test.txt") as fp: # "r" mode is default
for line in fp:
line = line.rstrip("\n")
if "Hello" in line:
line = "55" + line + "55"
if "World" in line:
line = "66" + line + "66"
new_file.append(line)
new_file = "\n".join(new_file)
print(new_file)
You need to iterate over each line of the file in order to get the desired result. In your code you are using .read(), instead use .readlines() to get list of all lines.
Below is the sample code:
lines = []
with open("test.txt", "r") as f:
for line in f.readlines(): # < Iterate over each line
if line.startswith("Hello"): # <-- check if line starts with "Hello"
line = "55{}55".format(line)
elif line.startswith("World"):
line = "66{}66".format(line)
lines.append(line)
print "\n".join(lines)
Why to use with? Check Python doc:
The ‘with‘ statement clarifies code that previously would use try...finally blocks to ensure that clean-up code is executed. In this section, I’ll discuss the statement as it will commonly be used. In the next section, I’ll examine the implementation details and show how to write objects for use with this statement.
The ‘with‘ statement is a control-flow structure whose basic structure is:
with expression [as variable]: with-block
The expression is evaluated, and it should result in an object that supports the context management protocol (that is, has enter() and exit() methods).
once you have read the file:
read_file = read_file.replace('hello','55hello55')
It'll replace all hellos with 55hello55
and use with open(text.txt, 'r' ) as file_hndler:
To read a text file, I recommend the following way which is compatible with Python 2 & 3:
import io
with io.open("test", mode="r", encoding="utf8") as fd:
...
Here, I make the assumption that your file use uft8 encoding.
Using a with statement make sure the file is closed at the end of reading even if a error occurs (an exception). To learn more about context manager, take a look at the Context Library.
There are several ways to read a text file:
read the whole file with: fd.read(), or
read line by line with a loop: for line in fd.
If you read the whole file, you'll need to split the lines (see str.splitlines. Here are the two solutions:
with io.open("test", mode="r", encoding="utf8") as fd:
content = fd.read()
for line in content.splilines():
if "Hello" in line:
print("55" + line + "55")
if "World" in line:
print("66" + line + "66")
Or
with io.open("test", mode="r", encoding="utf8") as fd:
for line in content.splilines():
line = line[:-1]
if "Hello" in line:
print("55" + line + "55")
if "World" in line:
print("66" + line + "66")
If you need to write the result in another file you can open the output file in write mode and use print(thing, file=out) as follow:
with io.open("test", mode="r", encoding="utf8") as fd:
with io.open("test", mode="w", encoding="utf8") as out:
for line in content.splilines():
line = line[:-1]
if "Hello" in line:
print("55" + line + "55", file=out)
if "World" in line:
print("66" + line + "66", file=out)
If you use Python 2, you'll need the following directive to use the print function:
from __future__ import print_function

Write a line above the current line in a file Python [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am looping through a file and I need to insert a text block above a line when it matches a particular string. Please help!
convBlockMoved = False
for line in outfile:
if(line.startswith('mappingSchemeAxis') and not convBlockMoved):
for convLine in conversionBlocks:
print convLine, #Print this above line
convBlockMoved = True
Note: conversionBlocks is a String array
Not a Python answer, but sed can do this in one line.
The file:
$ cat > so.txt
foo
bar
baz
qux
Insert before line baz:
$ sed -i '/baz/i11\n22\n33' so.txt
The result:
$ cat so.txt
foo
bar
11
22
33
baz
qux
So if your file is not huge, you can read all the lines at once and then work with lists. An example using the insert method of lists would be:
def main():
lines = []
with open('input.txt') as f:
lines = f.readlines()
ins_at = find_occurences_of('mappingSchemeAxis', lines)
for i in ins_at:
lines.insert(i,'HELLO WORLD\n')
with open('input.txt', 'w') as f:
f.writelines(lines)
def find_occurences_of(needle, haystack):
ret = []
for i, line in enumerate(haystack):
if line.startswith(needle):
ret.append(i)
return ret
if __name__ == '__main__':
main()
Basically, you are reading a list of strings and you want to put a new list element above the current one under some conditions.
What I would suggest you (if the file is not too big) is to append the lines from your input to an output list, appending the text you want before each lines that matche your conditions. Something like the following
for line in infile.readlines ():
if line.startswith ('mappingSchemeAxis'):
outcontent.append ('xxxxx')
outcontent.append (line)
for line in outcontent:
print (line) # here you want to write the content to the output file
I posted that a bit late :D
Try this:
def replace_import_in_f(f_in, pattern, plus):
with open(f_in) as f:
in_str = f.read()
in_str = re.sub(pattern, pattern + plus + "\n", in_str)
with open(f_in, "w") as f:
f.write(in_str)
Pattern must be the entire line that you would add the new line above.
Note: This is perfect for medium file due to the f.write() of the whole file content. (Test with python 3.4)
[UPDATE]
More complicated but to handle big files, use of coroutine to write to temp file during line processing. If not error replace the temp file.
import tempfile, os
def write_file(pattern="", plus=""):
with tempfile.NamedTemporaryFile(delete=False) as fin:
yield fin
while True:
line = (yield)
if pattern:
if line.startswith(pattern):
fin.write(bytes(plus, 'UTF-8'))
fin.write(bytes(line, 'UTF-8'))
def copy_file(path_in, path_out):
with open(path_in) as fin, open(path_out, "w") as fout:
for line in fin:
fout.write(line)
def read_and_file(fname, pattern="", plus=""):
try:
with open(fname) as fh:
# generator creation
gen_write = write_file(pattern, plus)
# get the tempfile
fout = next(gen_write)
for line in fh:
# send line
gen_write.send(line)
except (IOError, OSError) as e:
print(e)
else:
fout.close()
if os.name == "nt":
copy_file(fout.name, fname)
else:
os.rename(fout.name, fname)

Python: Parse file for a string and return value as variable

I'm trying to do, check if line in a config file contains a string ('string1') or not, and if so then print the string and a found message ('Found string1'). I need to store the found message as a variable.
The problem is exactly here (I don't have any results for print(line) and for print('Found string1'):
def get_version():
logger.info('Started')
for file in os.listdir(running_config_dir):
if file.endswith('.config'):
for line in file:
if str('string1') in line:
print(line)
print('Found string1')
else:
logger.critical('Running Configuration not found')
logger.info('Finished')
Here is my config file,
string1
string2
string3
file is a string, containing a filename. As such, iterating over the string gives you individual characters, not the contents of the file:
>>> file = 'foo'
>>> for line in file:
... print(line)
...
f
o
o
You need to open the filename to get a file object:
with open(file) as fileobj:
for line in fileobj:
Note that the '...' literal string syntax already produces a string object, there is no need to pass that to a str() call.
I'm not sure by what you mean with storing the found message as a variable; you already have access to the line variable, so you could just return that:
def get_version():
logger.info('Started')
version = None
for file in os.listdir(running_config_dir):
if file.endswith('.config'):
with open(file) as fileobj:
for line in fileobj:
if 'string1' in line:
print(line)
print('Found string1')
version = line.strip()
else:
logger.critical('Running Configuration not found')
logger.info('Finished')
return version

Python save output line into new file

I get some lines (a record) from log file, but I didn't know how to write function inside it to create a new log file whose name contains the current date in which to store those lines. I'm new python, so I hope you can give me solution. Thanks
def OnlyRecent(line):
if time.strptime(line.split("[")[0].strip(),"%a %b %d %H:%M:%S %Y")> time.gmtime(time.time()-(60*60*24*7)):
return True
return False
for line in f:
if OnlyRecent(line):
print line //store print lines into new log file. 20120911.log
You can redirect print output to a file:
log_file = open('mylog.log', 'w')
print>>log_file, 'hello'
log_file.close()
outside your loop
filename = time.strftime('%Y%m%d') + '.log'
f = open(filename, 'w')
do your loop here, and write each line with
f.write(line)
if you don't have a new line character in your line variable, do
f.write(line +'\n')
after exiting your loop
f.close()

Categories