Python - replace a line by its column in file - python

Sorry for posting such an easy question, but i couldn't find an answer on google.
I wish my code to do something like this
code:
lines = open("Bal.txt").write
lines[1] = new_value
lines.close()
p.s i wish to replace the line in a file with a value

xxx.dat before:
ddddddddddddddddd
EEEEEEEEEEEEEEEEE
fffffffffffffffff
with open('xxx.txt','r') as f:
x=f.readlines()
x[1] = "QQQQQQQQQQQQQQQQQQQ\n"
with open('xxx.txt','w') as f:
f.writelines(x)
xxx.dat after:
ddddddddddddddddd
QQQQQQQQQQQQQQQQQQQ
fffffffffffffffff
Note:f.read() returns a string, whereas f.readlines() returns a list, enabling you to replace an occurrence within that list.
Inclusion of the \n (Linux) newline character is important to separate line[1] from line[2] when you next read the file, or you would end up with:
ddddddddddddddddd
QQQQQQQQQQQQQQQQQQQfffffffffffffffff

Related

Concatenate lines with previous line based on number of letters in first column

New to coding and trying to figure out how to fix a broken csv file to make be able to work with it properly.
So the file has been exported from a case management system and contains fields for username, casenr, time spent, notes and date.
The problem is that occasional notes have newlines in them and when exporting the csv the tooling does not contain quotation marks to define it as a string within the field.
see below example:
user;case;hours;note;date;
tnn;123;4;solved problem;2017-11-27;
tnn;124;2;random comment;2017-11-27;
tnn;125;3;I am writing a comment
that contains new lines
without quotation marks;2017-11-28;
HJL;129;8;trying to concatenate lines to re form the broken csv;2017-11-29;
I would like to concatenate lines 3,4 and 5 to show the following:
tnn;125;3;I am writing a comment that contains new lines without quotation marks;2017-11-28;
Since every line starts with a username (always 3 letters) I thought I would be able to iterate the lines to find which lines do not start with a username and concatenate that with the previous line.
It is not really working as expected though.
This is what I have got so far:
import re
with open('Rapp.txt', 'r') as f:
for line in f:
previous = line #keep current line in variable to join next line
if not re.match(r'^[A-Za-z]{3}', line): #regex to match 3 letters
print(previous.join(line))
Script shows no output just finishes silently, any thoughts?
I think I would go a slightly different way:
import re
all_the_data = ""
with open('Rapp.txt', 'r') as f:
for line in f:
if not re.search("\d{4}-\d{1,2}-\d{1,2};\n", line):
line = re.sub("\n", "", line)
all_the_data = "".join([all_the_data, line])
print (all_the_data)
There a several ways to do this each with pros and cons, but I think this keeps it simple.
Loop the file as you have done and if the line doesn't end in a date and ; take off the carriage return and stuff it into all_the_data. That way you don't have to play with looking back 'up' the file. Again, lots of way to do this. If you would rather use the logic of starts with 3 letters and a ; and looking back, this works:
import re
all_the_data = ""
with open('Rapp.txt', 'r') as f:
all_the_data = ""
for line in f:
if not re.search("^[A-Za-z]{3};", line):
all_the_data = re.sub("\n$", "", all_the_data)
all_the_data = "".join([all_the_data, line])
print ("results:")
print (all_the_data)
Pretty much what was asked for. The logic being if the current line doesn't start right, take out the previous line's carriage return from all_the_data.
If you need help playing with the regex itself, this site is great: http://regex101.com
The regex in your code matches to all the lines (string) in the txt (finds a valid match to the pattern). The if condition is never true and hence nothing prints.
with open('./Rapp.txt', 'r') as f:
join_words = []
for line in f:
line = line.strip()
if len(line) > 3 and ";" in line[0:4] and len(join_words) > 0:
print(';'.join(join_words))
join_words = []
join_words.append(line)
else:
join_words.append(line)
print(";".join(join_words))
I've tried to not use regex here to keep it a little clear if possible. But, regex is a better option.
A simple way would be to use a generator that acts as a filter on the original file. That filter would concatenate a line to the previous one if it has not a semicolon (;) in its 4th column. Code could be:
def preprocess(fd):
previous = next(fd)
for line in fd:
if line[3] == ';':
yield previous
previous = line
else:
previous = previous.strip() + " " + line
yield previous # don't forget last line!
You could then use:
with open(test.txt) as fd:
rd = csv.DictReader(preprocess(fd))
for row in rd:
...
The trick here is that the csv module only requires on object that returns a line each time next function is applied to it, so a generator is appropriate.
But this is only a workaround and the correct way would be that the previous step directly produces a correct CSV file.

find line index in a text file python

I want to get the index of the line that corresponds to a certain string (in this case, InChI=1S/C11etc..) in a text file (content), here is my code:
with open('compounds.dat', encoding='utf-8', errors='ignore') as f:
content = f.readlines()
index = [x for x in range(len(content)) if "InChI=1S/C11H8O3/c1-6-5-9(13)10-7(11(6)14)3-2-4-8(10)12/h2-5" in content[x].lower()]
print(index)
However I get empty bracket []. But I am pretty sure that the line exist, because if I run this:
for line in f:
if u"InChI=1S/C11H8O3/c1-6-5-9(13)10-7(11(6)14)3-2-4-8(10)12/h2-5" in line:
l = line
I get the line I am interested.
Expanding upon my comment, calling lower() will lowercase your target string, while your search string has upper case letters - there's no chance you'll match anything like that.
Additionally, you don't have to iterate over the range. for can directly iterate over the items in content. This will work.
search_str = "InChI=1S/C11H8O3/c1-6-5-9(13)10-7(11(6)14)3-2-4-8(10)12/h2-5"
lines = [x for x in content if search_str in content]
Do not use .lower() in the code and it should work fine.

Python - Get specific characters from text file or from list

I have a text file with this in it
Curtain Open time: 8:00
When I wrote to the file I used this
File.write("Curtain Open Time: " + Var_CurtainOpenTime, + "\n")
I used the "\n" to go onto the next line for more data to be wrote. "Var_CurtainOpenTime" is a variable in this case it was "8:00". I have some code to read the line which looks like this:
FileRead = open('File.txt', 'r')
Printing this would read "Curtain Open Time: 8:00".
I want to be able to just get "8:00". I had previously used FileRead.split(" ") to separate each word but after the 8:00 I get ["Curtain", "Open", "Time:", "8:00\n"]. So I believe I would need to remove the first 3 indexes somehow and somehow remove '\n' from the last index. I don't know how I would approach this. Any help?
Try the following, I will comment the explain
with open('File.txt') as f:
[line.replace('\n','').split()[3:][0] for line in f][0]
or just:
FileRead = open('File.txt', 'r')
result = [line.replace('\n','').split()[3:][0] for line in FileRead][0]
you just need to change from the .split(" ") to .split() and then get the last list item
with open('file.txt') as f:
print f.read().split()[-1]
Well once you have the list from the split, you can remove the first 3 terms by doing l=l[3:] (where l is your list). Then you can remove the \n by doing s = s[:-1] where s is your desired string. This is using list slicing. You can look at documentation if you want to understand it further.

search value for key in file using python

I am new to Python.
Scenario:
apple=gravity search this pattern in file
search for apple if exist fetch corresponding value for apple,
if it is apple=gravity then case pass .
file structure (test.txt )
car=stop
green=go
apple=gravity
Please provide some suggestions as to how I can search value for key in file using Python
Sample:
f = open('test.txt', 'r')
wordCheck="apple=gravity";
for line in f:
if 'wordCheck' == line:
print ('found')
else:
print ('notfound')
break
Split your line with =
Check if apple is present in your first index! If true then, print the second index!
Note:
While reading lines from file, the '\n' character will be present. To get your line without \n read you content from file and use splitlines()!
To make it clean, strip the spaces from the beginning and end of your line to avoid glitches caused by spaces at the beginning and end of your line!
That is,
f = open('test.txt', 'r')
for line in map(str.strip,f.read().splitlines()):
line = line.split('=')
if 'apple' == line[0]:
print line[1]
else:
print ('notfound')
Output:
notfound
notfound
gravity
Hope it helps!
Iterating through the file directly as you are doing, is just fine, and considered more 'Pythonic' than readlines() (or indeed read().splitlines()).
Here, I strip the newline from each line and then split by the = to get the two halves.
Then, I test for the check word, and if present print out the other half of the line.
Note also that I have used the with context manager to open the file. This makes sure that the file is closed, even if an exception occurs.
with open('test.txt', 'r') as f:
wordcheck="apple"
for line in f:
key, val = line.strip().split('=')
if wordcheck == key:
print (val)
else:
print ('notfound')

python not writing when a space in text

I have working code which writes 'hi' in text file if 'Welcome' is present in the next line.
But, if the next line begins with whitespace before word 'Welcome' then it doesnot displays 'hi'
Code:
with open('afile.txt', 'r+') as f:
a = [x.rstrip() for x in f]
index = 0
for item in a:
if item.startswith("Welcome"):
a.insert(index, "hi")
break
index += 1
# Go to start of file and clear it
f.seek(0)
f.truncate()
# Write each line back
for line in a:
f.write(line + "\n")
Input: afile.txt
Welcome here
Good place
Expected output:
hi
Welcome here
Good place
I need to preserve my indendation also. How can I do that?
You are currently checking for Welcome directly. Instead, strip your line of whitespaces, and use the following condition instead
if item.strip().startswith("Welcome"):
EDIT
I see you've done rstrip earlier in a = [x.rstrip() for x in f]. Do a lstrip instead to remove whitespaces from the left. However, if you do this, your indentation will not be preserved.
In the line :
a = [x.rstrip() for x in f]
replace rstip with strip and you are good to go ...

Categories

Resources