I have 2 files - file1 and filee2. I want to search a Keyword in file1 and copy the next 2 lines of that keyword in file1 and store in variable. Then search the same keyword in file2 and replace the next 2 lines of the keyword in file2 with the variable.
File1:
file2:
For example I want to find the keyword [default] and copy next 2 lines of [default] then find the [default] in file 2 and replace the next two lines with file1.
Here is some code I quickly wrote.
file1 = open("file1.txt", "r") # opens the files
file2 = open("file2.txt", "r")
file1_contents = [line.replace("\n", "").replace(" ", "")
for line in file1.readlines()] # creates a list of the lines without whitespaces and newlines
file2_contents = [line.replace("\n", "").replace(" ", "")
for line in file2.readlines()]
file1.close() # closes the files
file2.close()
keyword = "[default]" # keyword to find
# trys to find the keyword in the list
try:
file1_index = file1_contents.index(keyword)
file1_vars = [file1_contents[file1_index + 1],
file1_contents[file1_index + 2]] # stores the two variables after the keyword
file2_index = file2_contents.index(keyword)
file2_contents[file2_index + 1] = file1_vars[0] # replaces them in file 2
file2_contents[file2_index + 2] = file1_vars[1]
file2_contents = [line + "\n" for line in file2_contents] # adds newlines
# writes the content back to file 2
with open("file2.txt", "w") as file:
file.writelines(file2_contents)
file.close()
except ValueError:
pass
Here is your code revised to get through the if statements. You need to remove the "\n" from the cont[i].
fn1 = open(r'<path>', 'r')
fn = open(r"<path>", "r")
profile = "[default]"
# read the content of the file line by line
cont = fn.readlines()
cont1 = fn1.readlines()
# print(type(cont[0]))
# print(type(profile))
for i in range(len(cont)):
if profile == (cont[i].replace("\n", "")):
#print("IF is passed")
profile_line1 = cont[i+1]
profile_line2 = cont[i+2]
# fn1.write(profile_line1)
print("profile 1 and 2 is", profile_line1, profile_line2)
else:
pass
for i in range(len(cont1)):
if profile == cont1[i].replace("\n", ""):
fn1_profile_line1 = cont1[i+1]
fn1_profile_line2 = cont1[i+2]
print(fn1_profile_line1)
print(fn1_profile_line2)
# fn1.write(profile_line1)
fn1.replace(cont1[i+1], profile_line1)
fn1.replace(cont1[i+2], profile_line2)
else:
pass
fn.close()
fn1.close()
Written code for this but if condition is not executing even it is True.
fn1 = open(r'<path>', 'r')
fn = open(r"<path>","r")
profile = "[default]"
# read the content of the file line by line
cont = fn.readlines()
cont1 = fn1.readlines()
#print(type(cont[0]))
#print(type(profile))
for i in range(len(cont)):
if str(profile) == (cont[i]):
#print("IF is passed")
profile_line1 = cont[i+1]
profile_line2 = cont[i+2]
#fn1.write(profile_line1)
print("profile 1 and 2 is",profile_line1,profile_line2)
else:
pass
for i in range(len(cont1)):
if str(profile) == str(cont1[i]):
fn1_profile_line1 = cont1[i+1]
fn1_profile_line2 = cont1[i+2]
print(fn1_profile_line1)
print(fn1_profile_line2)
#fn1.write(profile_line1)
fn1.replace(cont1[i+1], profile_line1)
fn1.replace(cont1[i+2], profile_line2)
else:
pass
fn.close()
fn1.close()
Related
I am writing a code in python where I am removing all the text after a specific word but in output lines are missing. I have a text file in unicode which have 3 lines:
my name is test1
my name is
my name is test 2
What I want is to remove text after word "test" so I could get the output as below
my name is test
my name is
my name is test
I have written a code but it does the task but also removes the second line "my name is"
My code is below
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index > 0:
txt += line[:index + len(splitStr)] + "\n"
with open(r"test.txt", "w") as fp:
fp.write(txt)
It looks like if there is no keyword found the index become -1.
So you are avoiding the lines w/o keyword.
I would modify your if by adding the condition as follows:
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index > 0:
txt += line[:index + len(splitStr)] + "\n"
elif index < 0:
txt += line
with open(r"test.txt", "w") as fp:
fp.write(txt)
No need to add \n because the line already contains it.
Your code does not append the line if the splitStr is not defined.
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index != -1:
txt += line[:index + len(splitStr)] + "\n"
else:
txt += line
with open(r"test.txt", "w") as fp:
fp.write(txt)
In my solution I simulate the input file via io.StringIO. Compared to your code my solution remove the else branch and only use one += operater. Also splitStr is set only one time and not on each iteration. This makes the code more clear and reduces possible errore sources.
import io
# simulates a file for this example
the_file = io.StringIO("""my name is test1
my name is
my name is test 2""")
txt = ""
splitStr = "test"
with the_file as fp:
# each line
for line in fp.readlines():
# cut somoething?
if splitStr in line:
# find index
index = line.find(splitStr)
# cut after 'splitStr' and add newline
line = line[:index + len(splitStr)] + "\n"
# append line to output
txt += line
print(txt)
When handling with files in Python 3 it is recommended to use pathlib for that like this.
import pathlib
file_path = pathlib.Path("test.txt")
# read from wile
with file_path.open('r') as fp:
# do something
# write back to the file
with file_path.open('w') as fp:
# do something
Suggestion:
for line in fp.readlines():
i = line.find('test')
if i != -1:
line = line[:i]
Hello can someone fix it I tried to find solution online but nothing work.
Python Version: 3.7.9
if engine == "example1":
search = example1(engine)
request = partial(search.search_for, string)
all = p.map(request, pages)
elif engine == "example2":
filepath = "list.txt"
with open(filepath) as fp:
line = fp.readline()
count = 1
while line:
search = example2(engine)
request = partial(search.search_for, line.strip())
all = p.map(request, pages)
line = fp.readline()
count += 1
input(" press close to exit ")
It appears that the biggest issue is with lines immediately following your with statement. Those should be indented to be part of the context manager scope.
elif engine == "example2":
filepath = "list.txt"
with open(filepath) as fp:
line = fp.readline() # <--- note indent
count = 1 # <--- note indent
while line:
search = example2(engine)
request = partial(search.search_for, line.strip())
all = p.map(request, pages)
line = fp.readline()
count += 1
Here you have 2 intent mistakes.copy this code and try it
if engine == "example1":
search = example1(engine)
request = partial(search.search_for, string)
all = p.map(request, pages)
1. In elif there is one space before the line
elif engine == "example2":
filepath = "list.txt"
2.After the next line With open you need to leave 4 spaces
with open(filepath) as fp:
line = fp.readline()
count = 1
while line:
search = example2(engine)
request = partial(search.search_for, line.strip())
all = p.map(request, pages)
line = fp.readline()
count += 1
input(" press close to exit ")
I have a script that outputs a text file (Mod_From_SCRSTXT.txt). I need to delete the first line of that file.
I have tried changing the last line of the find function shown below. The first line still get printed in the new file created even with the changes.
def find(substr, infile, outfile):
with open(infile) as a, open(outfile, 'a') as b:
for line in a:
if substr in line:
b.write(line[1:])
srcn_path1 = input(" Enter Path. Example: U:\...\...\SRCNx\SCRS.TXT\n" +
" Enter SRCS.TXT's Path: ")
print ()
scrNumber1 = input(' Enter SCR number: ')
print ()
def find(substr, infile, outfile):
with open(infile) as a, open(outfile, 'a') as b:
for line in a:
if substr in line:
b.write(line) # or (line + '\n')
# action station:
find(scrNumber1, srcn_path1, 'Mod_From_SCRSTXT.txt')
Actual result:
VSOAU-0004 16999
VSOAU-0004
VSOAU-0004
VSOAU-0004
VSOAU-0004
Expected result:
VSOAU-0004
VSOAU-0004
VSOAU-0004
VSOAU-0004
You'll want to make a minor adjustment:
You can either count the lines in the file:
numberOfLines = 0
for line in file:
numberOfLines += 1
for line in range(1, linesInFile + 1):
Or you can ignore the first line through many different ways, this being a simple one:
ignoredLine = 0
for line in file:
if not ignoredLine:
ignoredLine = 1
else:
#Do stuff with the other lines
import pathlib
import os
import copy
import io
def delete_first_line(read_path):
try:
read_path = pathlib.Path(str(read_path))
write_path = str(copy.copy(read_path)) + ".temp"
while os.path.exists(write_path):
write_path = write_path + ".temp"
with open(read_path , mode = "r") as inf:
with open(write_path, mode="w") as outf:
it_inf = iter(inf)
next(it_inf) # discard first line
for line in it_inf:
print(line, file = outf)
os.remove(read_path)
os.rename(write_path, read_path)
except StopIteration:
with io.StringIO() as string_stream:
print(
"Cannot remove first line from an empty file",
read_path,
file = string_stream,
sep = "\n"
)
msg = string_stream.getvalue()
raise ValueError(msg)
except FileNotFoundError:
with io.StringIO() as string_stream:
print(
"Cannot remove first line from non-existant file",
read_path,
file = string_stream,
sep = "\n"
)
msg = string_stream.getvalue()
raise ValueError(msg)
finally:
pass
return
I tried to search for similar questions, but I couldn't find. Please mark as a duplicate if there is similar questions available.
I'm trying to figure out a way to read and gather multiple information from single file. Here in the file Block-A,B & C are repeated in random order and Block-C has more than one information to capture. Every block end with 'END' text. Here is the input file:
Block-A:
(info1)
END
Block-B:
(info2)
END
Block-C:
(info3)
(info4)
END
Block-C:
(info7)
(info8)
END
Block-A:
(info5)
END
Block-B:
(info6)
END
Here is my code:
import re
out1 = out2 = out3 = ""
a = b = c = False
array=[]
with open('test.txt', 'r') as f:
for line in f:
if line.startswith('Block-A'):
line = next(f)
out1 = line
a = True
if line.startswith('Block-B'):
line=next(f)
out2 = line
b = True
if line.startswith('Block-C'):
c = True
if c:
line=next(f)
if not line.startswith('END\n'):
out3 = line
array.append(out3.strip())
if a == b == c == True:
print(out1.rstrip() +', ' + out2.rstrip() + ', ' + str(array))
a = b = c = False
array=[]
Thank you in advance for your valuable inputs.
Use a dictionary for the datas from each block. When you read the line that starts a block, set a variable to that name, and use it as the key into the dictionary.
out = {}
with open('test.txt', 'r') as f:
for line in f:
if line.endswidth(':'):
blockname = line[:-1]
if not blockname in out:
out[blockname] = ''
elif line == 'END'
blockname = None
else if blockname:
out[blockname] += line
print(out)
If you don't want the Block-X to print, unhash the elif statment
import os
data = r'/home/x/Desktop/test'
txt = open(data, 'r')
for line in txt.readlines():
line = line[:-1]
if line in ('END'):
pass
#elif line.startswith('Block'):
# pass
else:
print line
>>>>
Block-A:
(info1)
Block-B:
(info2)
Block-C:
(info3)
(info4)
Block-C:
(info7)
(info8)
Block-A:
(info5)
Block-B:
(info6)
I'm in trouble here. I need to read a file. Txt file that contains a sequence of records, check the records that I want to copy them to a new file.
The file content is like this (this is just an example, the original file has more than 30 000 lines):
AAAAA|12|120 #begin file
00000|46|150 #begin register
03000|TO|460
99999|35|436 #end register
00000|46|316 #begin register
03000|SP|467
99999|33|130 #end register
00000|46|778 #begin register
03000|TO|478
99999|33|457 #end register
ZZZZZ|15|111 #end file
The records that begin with 03000 and have the characters 'TO' must be written to a new file. Based on the example, the file should look like this:
AAAAA|12|120 #begin file
00000|46|150 #begin register
03000|TO|460
99999|35|436 #end register
00000|46|778 #begin register
03000|TO|478
99999|33|457 #end register
ZZZZZ|15|111 #end file
Code:
file = open("file.txt",'r')
newFile = open("newFile.txt","w")
content = file.read()
file.close()
# here I need to check if the record exists 03000 characters 'TO', if it exists, copy the recordset 00000-99999 for the new file.
I did multiple searches and found nothing to help me.
Thank you!
with open("file.txt",'r') as inFile, open("newFile.txt","w") as outFile:
outFile.writelines(line for line in inFile
if line.startswith("03000") and "TO" in line)
If you need the previous and the next line, then you have to iterate inFile in triads. First define:
def gen_triad(lines, prev=None):
after = current = next(lines)
for after in lines:
yield prev, current, after
prev, current = current, after
And then do like before:
outFile.writelines(''.join(triad) for triad in gen_triad(inFile)
if triad[1].startswith("03000") and "TO" in triad[1])
import re
pat = ('^00000\|\d+\|\d+.*\n'
'^03000\|TO\|\d+.*\n'
'^99999\|\d+\|\d+.*\n'
'|'
'^AAAAA\|\d+\|\d+.*\n'
'|'
'^ZZZZZ\|\d+\|\d+.*')
rag = re.compile(pat,re.MULTILINE)
with open('fifi.txt','r') as f,\
open('newfifi.txt','w') as g:
g.write(''.join(rag.findall(f.read())))
For files with additional lines between lines beginning with 00000, 03000 and 99999, I didn't find simpler code than this one:
import re
pat = ('(^00000\|\d+\|\d+.*\n'
'(?:.*\n)+?'
'^99999\|\d+\|\d+.*\n)'
'|'
'(^AAAAA\|\d+\|\d+.*\n'
'|'
'^ZZZZZ\|\d+\|\d+.*)')
rag = re.compile(pat,re.MULTILINE)
pit = ('^00000\|.+?^03000\|TO\|\d+.+?^99999\|')
rig = re.compile(pit,re.DOTALL|re.MULTILINE)
def yi(text):
for g1,g2 in rag.findall(text):
if g2:
yield g2
elif rig.match(g1):
yield g1
with open('fifi.txt','r') as f,\
open('newfifi.txt','w') as g:
g.write(''.join(yi(f.read())))
file = open("file.txt",'r')
newFile = open("newFile.txt","w")
content = file.readlines()
file.close()
newFile.writelines(filter(lambda x:x.startswith("03000") and "TO" in x,content))
This seems to work. The other answers seem to only be writing out records that contain '03000|TO|' but you have to write out the record before and after that as well.
import sys
# ---------------------------------------------------------------
# ---------------------------------------------------------------
# import file
file_name = sys.argv[1]
file_path = 'C:\\DATA_SAVE\\pick_parts\\' + file_name
file = open(file_path,"r")
# ---------------------------------------------------------------
# create output files
output_file_path = 'C:\\DATA_SAVE\\pick_parts\\' + file_name + '.out'
output_file = open(output_file_path,"w")
# create output files
# ---------------------------------------------------------------
# process file
temp = ''
temp_out = ''
good_write = False
bad_write = False
for line in file:
if line[:5] == 'AAAAA':
temp_out += line
elif line[:5] == 'ZZZZZ':
temp_out += line
elif good_write:
temp += line
temp_out += temp
temp = ''
good_write = False
elif bad_write:
bad_write = False
temp = ''
elif line[:5] == '03000':
if line[6:8] != 'TO':
temp = ''
bad_write = True
else:
good_write = True
temp += line
temp_out += temp
temp = ''
else:
temp += line
output_file.write(temp_out)
output_file.close()
file.close()
Output:
AAAAA|12|120 #begin file
00000|46|150 #begin register
03000|TO|460
99999|35|436 #end register
00000|46|778 #begin register
03000|TO|478
99999|33|457 #end register
ZZZZZ|15|111 #end file
Does it have to be python? These shell commands would do the same thing in a pinch.
head -1 inputfile.txt > outputfile.txt
grep -C 1 "03000|TO" inputfile.txt >> outputfile.txt
tail -1 inputfile.txt >> outputfile.txt
# Whenever I have to parse text files I prefer to use regular expressions
# You can also customize the matching criteria if you want to
import re
what_is_being_searched = re.compile("^03000.*TO")
# don't use "file" as a variable name since it is (was?) a builtin
# function
with open("file.txt", "r") as source_file, open("newFile.txt", "w") as destination_file:
for this_line in source_file:
if what_is_being_searched.match(this_line):
destination_file.write(this_line)
and for those who prefer a more compact representation:
import re
with open("file.txt", "r") as source_file, open("newFile.txt", "w") as destination_file:
destination_file.writelines(this_line for this_line in source_file
if re.match("^03000.*TO", this_line))
code:
fileName = '1'
fil = open(fileName,'r')
import string
##step 1: parse the file.
parsedFile = []
for i in fil:
##tuple1 = (1,2,3)
firstPipe = i.find('|')
secondPipe = i.find('|',firstPipe+1)
tuple1 = (i[:firstPipe],\
i[firstPipe+1:secondPipe],\
i[secondPipe+1:i.find('\n')])
parsedFile.append(tuple1)
fil.close()
##search criterias:
searchFirst = '03000'
searchString = 'TO' ##can be changed if and when required
##step 2: used the parsed contents to write the new file
filout = open('newFile','w')
stringToWrite = parsedFile[0][0] + '|' + parsedFile[0][1] + '|' + parsedFile[0][2] + '\n'
filout.write(stringToWrite) ##to write the first entry
for i in range(1,len(parsedFile)):
if parsedFile[i][1] == searchString and parsedFile[i][0] == searchFirst:
for j in range(-1,2,1):
stringToWrite = parsedFile[i+j][0] + '|' + parsedFile[i+j][1] + '|' + parsedFile[i+j][2] + '\n'
filout.write(stringToWrite)
stringToWrite = parsedFile[-1][0] + '|' + parsedFile[-1][1] + '|' + parsedFile[-1][2] + '\n'
filout.write(stringToWrite) ##to write the first entry
filout.close()
I know that this solution may be a bit long. But it is quite easy to understand. And it seems an intuitive way to do it. And I have already checked this with the Data that you have provided and it works perfectly.
Please tell me if you need some more explanation on the code. I will definitely add the same.
I tip (Beasley and Joran elyase) very interesting, but it only allows to get the contents of the line 03000. I would like to get the contents of the lines 00000 to line 99999.
I even managed to do here, but I am not satisfied, I wanted to make a more cleaner.
See how I did:
file = open(url,'r')
newFile = open("newFile.txt",'w')
lines = file.readlines()
file.close()
i = 0
lineTemp = []
for line in lines:
lineTemp.append(line)
if line[0:5] == '03000':
state = line[21:23]
if line[0:5] == '99999':
if state == 'TO':
newFile.writelines(lineTemp)
else:
linhaTemp = []
i = i+1
newFile.close()
Suggestions...
Thanks to all!