Alternatively, I tried this, but it doesnt seem to get rid of the rows that have blank spaces (blank rows included in the number of rows I'd like to delete). Meanwhile, the code above appears to get rid of those blank spaces, but there is line termination.
next(filecsv) for i in range(10)
Use fileinput.input() with the inplace update file option:
from __future__ import print_function
import fileinput
skip_rows = int(input('How many rows to skip? '))
f = fileinput.input('input.csv', inplace=True)
for i in range(skip_rows):
f.readline()
for row in f:
print(row, end='')
This will skip the first skip_rows rows of the input file and overwrite it without you having to manage writing and moving a temporary file.
(You can omit importing print_function if you are using Python 3)
There are quite a few ways to grab input from a command line tool (which is what I am inferring you wrote). Here are a couple:
Option 1: created in a file called out.py
use sys.argv
import sys
arg1 = sys.argv[1]
print("passed in value: %s" % arg1)
Then run it by passing in an argument (note index 1, script is index 0)
python out.py cell1
passed in value: cell1
Option 2:
A potentially better way is to use a commandline tool framework like click: http://click.pocoo.org/5/. This has almost everything you could ever want to do, and they handle much of the hard logic for you.
You can prompt the user with a simple while loop and listen into standard input or using the input() function.
As to your question on how to delete lines in a file, you can read in the file as a list of lines.
lines=[]
with open('input.txt') as f:
lines=f.readlines()
You can then write back into the file everything past the lines you want to skip by using list slicing.
Also I am pretty sure similar questions have been asked before, try to Google or search Stack Overflow for your question or a subset of your question next time.
P.S.
I also want to add that if you are reading a very large file, it would be better if you read a line at a time, and outputted to a separate file. For a large enough file, you might run out of RAM to hold the file in memory.
Firstly I have opened up the csv file [...]
Did you consider to use pandas to process your data?
If so, pandas.read_csv, allows to skip lines using the skiprows parameter.
You will typically use an iterator to read files. You could do something like this:
numToSkip = 3
with open('somefile.txt') as f:
for i, line in enumerate(f):
if i < numToSkip : continue
# Do 'whatnot' processing here
Related
Is there a way to precurse a write function in python (I'm working with fasta files but any write function that works with text files should work)?
The only way I could think is to read the whole file in as an array and count the number of lines I want to start at and just re-write that array, at that value, to a text file.
I was just thinking there might be a write an option or something somewhere.
I would add some code, but I'm writing it right now, and everyone on here seems to be pretty well versed, and probably know what I'm talking about. I'm an EE in the CS domain and just calling on the StackOverflow community to enlighten me.
From what I understand you want to truncate a file from the start - i.e remove the first n lines.
Then no - there is no way you can do without reading in the lines and ignoring the lines - this is what I would do :
import shutil
remove_to = 5 # Remove lines 0 to 5
try:
with open('precurse_me.txt') as inp, open('temp.txt') as out:
for index, line in enumerate(inp):
if index <= remove_to:
continue
out.write(line)
# If you don't want to replace the original file - delete this
shutil.move('temp.txt', 'precurse_me.txt')
except Exception as e:
raise e
Here I open a file for the output and then use shutil.move() to replace the input file only after the processing (the for loop) is complete. I do this so that I don't break the 'precurse_me.txt' file in case the processing fails. I wrap the whole thing in a try/except so that if anything fails it doesn't try to move the file by accident.
The key is the for loop - read the input file line by line; using the enumerate() function to count the lines as they come in.
Ignore those lines (by using continue) until the index says to not ignore the line - after that simply write each line to the out file.
I have quite a bunch of data; More prcisely, a 8 GB rpt file;
Now before processing it I want to know how many rows there actually are - this helps me to later find out how long the processing will take etc;
Now reading an rpt file of that size in python as a whole obviously does not work so I need to read line by line; To find out the number of lines I wrote that simple python script:
import pandas as pd
counter=0
for line in pd.read_fwf("test.rpt", chunksize=1):
counter=counter+1
print(counter)
This seems to work well - however I realized that it is quite slow and to really read all the lines is unnecessary;
Is there a way to get the number of rows without reading each line?
Many thanks
I'm not familiar with the .rpt file format, but if it can be read in as a text file (which I'm assuming it can if you're using pd.read_fwf) then you can probably just use Python's builtins for input/output.
with open('test.rpt', 'r') as testfile:
for i, line in enumerate(testfile):
pass
# Add one to get the line count
print(i+1)
This will allow you to (efficiently) iterate over each line of the file object. The builtin enumerate function will count each line as you read it.
You don't need to use python. Using
wc -l
would be the right tool for that job.
I have this code for opening a big file:
fr = open('X1','r')
text = fr.read()
print(text)
fr.close()
When I open it with gedit, the file is something like this with the number of each row:
but in terminal it is shown without any row number:
So, it is difficult to distinguish among different rows.
How can I add the number of rows in my python script?
If you just want to show the number of the line, wrap the line iterator in enumerate, it will return a iterator of tuples with the index (zero based) and the line.
Like this:
with open('X1', 'r') as fr:
for index, line in enumerate(fr):
print(f'{index}: {line}')
Also, when working with files, using the context manager with with is better. It ensures proper closing and flushing the data buffers even if an exception is raised
EDIT:
As a bonus, the example I gave uses only iterators, the file object is a iterator of lines and enumerate also returns a iterator that builds the tuple.
This means that this script only holds only line at a time in memory (and the buffers defined by your platform), not the whole file.
fr = open('X1','r')
rowcount=0
for i in fr:
print(rowcount,end="")
print(":",end="")
print(i)
rowcount+=1
print(rowcount)
fr.close()
We have just read file line by line and printing counter each time.
Noob question here. I'm scheduling a cron job for a Python script for every 2 hours, but I want the script to stop running after 48 hours, which is not a feature of cron. To work around this, I'm recording the number of executions at the end of the script in a text file using a tally mark x and opening the text file at the beginning of the script to only run if the count is less than n.
However, my script seems to always run regardless of the conditions. Here's an example of what I've tried:
with open("curl-output.txt", "a+") as myfile:
data = myfile.read()
finalrun = "xxxxx"
if data != finalrun:
[CURL CODE]
with open("curl-output.txt", "a") as text_file:
text_file.write("x")
text_file.close()
I think I'm missing something simple here. Please advise if there is a better way of achieving this. Thanks in advance.
The problem with your original code is that you're opening the file in a+ mode, which seems to set the seek position to the end of the file (try print(data) right after you read the file). If you use r instead, it works. (I'm not sure that's how it's supposed to be. This answer states it should write at the end, but read from the beginning. The documentation isn't terribly clear).
Some suggestions: Instead of comparing against the "xxxxx" string, you could just check the length of the data (if len(data) < 5). Or alternatively, as was suggested, use pickle to store a number, which might look like this:
import pickle
try:
with open("curl-output.txt", "rb") as myfile:
num = pickle.load(myfile)
except FileNotFoundError:
num = 0
if num < 5:
do_curl_stuff()
num += 1
with open("curl-output.txt", "wb") as myfile:
pickle.dump(num, myfile)
Two more things concerning your original code: You're making the first with block bigger than it needs to be. Once you've read the string into data, you don't need the file object anymore, so you can remove one level of indentation from everything except data = myfile.read().
Also, you don't need to close text_file manually. with will do that for you (that's the point).
Sounds more for a job scheduling with at command?
See http://www.ibm.com/developerworks/library/l-job-scheduling/ for different job scheduling mechanisms.
The first bug that is immediately obvious to me is that you are appending to the file even if data == finalrun. So when data == finalrun, you don't run curl but you do append another 'x' to the file. On the next run, data will be not equal to finalrun again so it will continue to execute the curl code.
The solution is of course to nest the code that appends to the file under the if statement.
Well there probably is an end of line jump \n character which makes that your file will contain something like xx\n and not simply xx. Probably this is why your condition does not work :)
EDIT
What happens if through the python command line you type
open('filename.txt', 'r').read() # where filename is the name of your file
you will be able to see whether there is an \n or not
Try using this condition along with if clause instead.
if data.count('x')==24
data string may contain extraneous data line new line characters. Check repr(data) to see if it actually a 24 x's.
The Problem - Update:
I could get the script to print out but had a hard time trying to figure out a way to put the stdout into a file instead of on a screen. the below script worked on printing results to the screen. I posted the solution right after this code, scroll to the [ solution ] at the bottom.
First post:
I'm using Python 2.7.3. I am trying to extract the last words of a text file after the colon (:) and write them into another txt file. So far I am able to print the results on the screen and it works perfectly, but when I try to write the results to a new file it gives me str has no attribute write/writeline. Here it the code snippet:
# the txt file I'm trying to extract last words from and write strings into a file
#Hello:there:buddy
#How:areyou:doing
#I:amFine:thanks
#thats:good:I:guess
x = raw_input("Enter the full path + file name + file extension you wish to use: ")
def ripple(x):
with open(x) as file:
for line in file:
for word in line.split():
if ':' in word:
try:
print word.split(':')[-1]
except (IndexError):
pass
ripple(x)
The code above works perfectly when printing to the screen. However I have spent hours reading Python's documentation and can't seem to find a way to have the results written to a file. I know how to open a file and write to it with writeline, readline, etc, but it doesn't seem to work with strings.
Any suggestions on how to achieve this?
PS: I didn't add the code that caused the write error, because I figured this would be easier to look at.
End of First Post
The Solution - Update:
Managed to get python to extract and save it into another file with the code below.
The Code:
inputFile = open ('c:/folder/Thefile.txt', 'r')
outputFile = open ('c:/folder/ExtractedFile.txt', 'w')
tempStore = outputFile
for line in inputFile:
for word in line.split():
if ':' in word:
splitting = word.split(':')[-1]
tempStore.writelines(splitting +'\n')
print splitting
inputFile.close()
outputFile.close()
Update:
checkout droogans code over mine, it was more efficient.
Try this:
with open('workfile', 'w') as f:
f.write(word.split(':')[-1] + '\n')
If you really want to use the print method, you can:
from __future__ import print_function
print("hi there", file=f)
according to Correct way to write line to file in Python. You should add the __future__ import if you are using python 2, if you are using python 3 it's already there.
I think your question is good, and when you're done, you should head over to code review and get your code looked at for other things I've noticed:
# the txt file I'm trying to extract last words from and write strings into a file
#Hello:there:buddy
#How:areyou:doing
#I:amFine:thanks
#thats:good:I:guess
First off, thanks for putting example file contents at the top of your question.
x = raw_input("Enter the full path + file name + file extension you wish to use: ")
I don't think this part is neccessary. You can just create a better parameter for ripple than x. I think file_loc is a pretty standard one.
def ripple(x):
with open(x) as file:
With open, you are able to mark the operation happening to the file. I also like to name my file object according to its job. In other words, with open(file_loc, 'r') as r: reminds me that r.foo is going to be my file that is being read from.
for line in file:
for word in line.split():
if ':' in word:
First off, your for word in line.split() statement does nothing but put the "Hello:there:buddy" string into a list: ["Hello:there:buddy"]. A better idea would be to pass split an argument, which does more or less what you're trying to do here. For example, "Hello:there:buddy".split(":") would output ['Hello', 'there', 'buddy'], making your search for colons an accomplished task.
try:
print word.split(':')[-1]
except (IndexError):
pass
Another advantage is that you won't need to check for an IndexError, since you'll have, at least, an empty string, which when split, comes back as an empty string. In other words, it'll write nothing for that line.
ripple(x)
For ripple(x), you would instead call ripple('/home/user/sometext.txt').
So, try looking over this, and explore code review. There's a guy named Winston who does really awesome work with Python and self-described newbies. I always pick up new tricks from that guy.
Here is my take on it, re-written out:
import os #for renaming the output file
def ripple(file_loc='/typical/location/while/developing.txt'):
outfile = "output.".join(os.path.basename(file_loc).split('.'))
with open(outfile, 'w') as w:
lines = open(file_loc, 'r').readlines() #everything is one giant list
w.write('\n'.join([line.split(':')[-1] for line in lines]))
ripple()
Try breaking this down, line by line, and changing things around. It's pretty condensed, but once you pick up comprehensions and using lists, it'll be more natural to read code this way.
You are trying to call .write() on a string object.
You either got your arguments mixed up (you'll need to call fileobject.write(yourdata), not yourdata.write(fileobject)) or you accidentally re-used the same variable for both your open destination file object and storing a string.