I've got the following code:
with open("test.txt", "r") as test, open("table.txt", "w") as table:
reader = csv.reader(test, delimiter="\t")
writer = csv.writer(table, delimiter="\t")
for row in reader:
if all(field not in keywords for field in row):
writer.writerow(row)
How am I able to convert it to a .py file which let you define table.txt and test when you run it. So that one have to write:
Script.py test.txt output.txt
Just use sys.argv:
import sys
import csv
with open(sys.argv[1], "r") as test, open(sys.argv[2], "w") as table:
# more here
Note, sys.argv[0] contains the script name (in your case, Script.py). To get the first argument, you should get sys.argv[1]; to get the second argument, you should get sys.argv[2] and so on.
Related
I need to write something into files, which I am passing through command line in python. I am using the below code mycode.py
import csv
import sys
path = sys.argv[1]
row = ['4', ' Danny', ' New York']
with open(r"path" , 'w') as csvFile:
writer = csv.writer(csvFile)
writer.writerow(row)
When I execute it, the file is not written, but when I hardcode path as
with open(r"C:\Users\venkat\Desktop\python\sam.csv", 'w') as
csvFile:
the file is being written, Please let me know if I am missing anything.
One more requirement is I have to pass only the directory in open, and append some file name.
For example: I can pass
C:\Users\venkat\Desktop\python, sam.csv
I have to append to the directory in code.
You should use the path variable's value.
Replace
with open(r"path" , 'w') as csvFile:
with
with open(path , 'w') as csvFile:
^^^^
If you want to append one file to a directory path, you could use os package.
file_path = os.path.join(path, file)
Well this worked
import csv
import sys
path = sys.argv[1]
row = ['4', ' Danny', ' New York']
with open(path, 'w') as csvFile:
writer = csv.writer(csvFile)
writer.writerow(row)
If you want to append(or write) an existing file,this worked too using format:
path="insert\\pathOf\\file.txt"
with open("{}".format(path),'a') as file:
file.write("excellent\n")
The 'a' is for append,so it will add the 'excellent' string to file.txt.
If you want to write a new file just put 'w' instead of 'a'.
Using 'w' will overwrite the file.txt if already exists.
The \n is for ending in new line so if you run the same code 2 times it will add 'excellent' in two different lines and not side by side.
You should add curly braces if you want to convert it to raw format
with open(rf"{path}" , 'w') as csvFile:
This is my test code, but I have a more elaborate one - but they both don't work. In python 3.x.
import sys
def main():
inputfile = 'hi'
print(inputfile)
if __name__ == '__main__':
main()
EDIT: This what I want to use the terminal for (and syntax errors - same problem):
import csv
import sys
import json
inputfile = sys.argv[1]
outputfile = sys.argv[2]
# reading the csv
with open(inputfile, 'r') as inhandle: # r is reading while w is writing
reader = csv.DictReader(inhandle)
data = []
for row in reader:
data.append(row)
print(data)
# writing the json
with open(outputfile, "W") as outhandle:
json.dump(data, outhandle, indent=2)
As far as I understood by the code you've attached, hi must be wrote as 'hi'. In your original code, hi is regarded as another variable being assigned to inputfile, but it's not defined yet.
I want to be able to read whatever csv file i have on my laptop and not just that specific one. how can i fix my code to ask the user to enter the input file name on the command line?
ifile = open('esxtopresult.csv', 'rb')
reader = csv.reader(ifile)
ofile = open('esxtopresult_mod2.csv', 'wb')
writer = csv.writer(ofile)
Simply you can get all your arguments like this:
import sys
print sys.argv[1]
ifile = open(sys.argv[1], 'rb')
writer = csv.writer(ofile)
>>python code.py test/test.csv
I am trying to create .csv file.
For some reason it skips line before printing entry.
Here is the output
But here is what I need
Below is code. Apparently if line != "": doesn't work
import csv
#-----------------------------------
def csv_writer(data,path):
"""
Write data to a CSV file path
"""
with open(path, "w") as csv_file:
writer = csv.writer(csv_file, delimiter=',')
for line in data:
if line != "":
writer.writerow(line)
#-----------------------------------
if __name__ == "__main__":
data = ["first_name,last_name,city".split(","),
"Tyrese,Hirthe,Strackeport".split(","),
"Jules,Dicki,Lake Nickolasville".split(","),
"Dedric,Medhurst,Stiedemannberg".split(",")
]
path = "output.csv"
csv_writer(data,path)
Some python versions (on windows) have an issue with that with open(path, "w") as csv_file:. A spurious carriage return char is inserted, creating a blank line after each line.
You have to add newline="" as stated in the documentation. Python 3:
with open(path, "w",newline="") as csv_file:
writer = csv.writer(csv_file, delimiter=',')
As for python 2:
with open(path, "wb") as csv_file:
writer = csv.writer(csv_file, delimiter=',')
see also:
portable way to write csv file in python 2 or python 3
csv writer expected byte like and space between rows
(note that latest Python versions on Windows don't need this anymore, but the documentation continues to state it)
When you open the file you need to pass the keyword argument newline with a blank string. This will prevent the newlines being added between rows. Your function should be:
def csv_writer(data,path):
"""
Write data to a CSV file path
"""
with open(path, "w", newline = '') as csv_file:
writer = csv.writer(csv_file, delimiter=',')
for line in data:
if line:
writer.writerow(line)
Note that this is only an issue on Windows.
I have a Python script which modifies a CSV file to add the filename as the last column:
import sys
import glob
for filename in glob.glob(sys.argv[1]):
file = open(filename)
data = [line.rstrip() + "," + filename for line in file]
file.close()
file = open(filename, "w")
file.write("\n".join(data))
file.close()
Unfortunately, it also adds the filename to the header (first) row of the file. I would like the string "ID" added to the header instead. Can anybody suggest how I could do this?
Have a look at the official csv module.
Here are a few minor notes on your current code:
It's a bad idea to use file as a variable name, since that shadows the built-in type.
You can close the file objects automatically by using the with syntax.
Don't you want to add an extra column in the header line, called something like Filename, rather than just omitting a column in the first row?
If your filenames have commas (or, less probably, newlines) in them, you'll need to make sure that the filename is quoted - just appending it won't do.
That last consideration would incline me to use the csv module instead, which will deal with the quoting and unquoting for you. For example, you could try something like the following code:
import glob
import csv
import sys
for filename in glob.glob(sys.argv[1]):
data = []
with open(filename) as finput:
for i, row in enumerate(csv.reader(finput)):
to_append = "Filename" if i == 0 else filename
data.append(row+[to_append])
with open(filename,'wb') as foutput:
writer = csv.writer(foutput)
for row in data:
writer.writerow(row)
That may quote the data slightly differently from your input file, so you might want to play with the quoting options for csv.reader and csv.writer described in the documentation for the csv module.
As a further point, you might have good reasons for taking a glob as a parameter rather than just the files on the command line, but it's a bit surprising - you'll have to call your script as ./whatever.py '*.csv' rather than just ./whatever.py *.csv. Instead, you could just do:
for filename in sys.argv[1:]:
... and let the shell expand your glob before the script knows anything about it.
One last thing - the current approach you're taking is slightly dangerous, in that if anything fails when writing back to the same filename, you'll lose data. The standard way of avoiding this is to instead write to a temporary file, and, if that was successful, rename the temporary file over the original. So, you might rewrite the whole thing as:
import csv
import sys
import tempfile
import shutil
for filename in sys.argv[1:]:
tmp = tempfile.NamedTemporaryFile(delete=False)
with open(filename) as finput:
with open(tmp.name,'wb') as ftmp:
writer = csv.writer(ftmp)
for i, row in enumerate(csv.reader(finput)):
to_append = "Filename" if i == 0 else filename
writer.writerow(row+[to_append])
shutil.move(tmp.name,filename)
You can try:
data = [file.readline().rstrip() + ",id"]
data += [line.rstrip() + "," + filename for line in file]
You can try changing your code, but using the csv module is recommended. This should give you the result you want:
import sys
import glob
import csv
filename = glob.glob(sys.argv[1])[0]
yourfile = csv.reader(open(filename, 'rw'))
csv_output=[]
for row in yourfile:
if len(csv_output) != 0: # skip the header
row.append(filename)
csv_output.append(row)
yourfile = csv.writer(open(filename,'w'),delimiter=',')
yourfile.writerows(csv_output)
Use the CSV module that comes with Python.
import csv
import sys
def process_file(filename):
# Read the contents of the file into a list of lines.
f = open(filename, 'r')
contents = f.readlines()
f.close()
# Use a CSV reader to parse the contents.
reader = csv.reader(contents)
# Open the output and create a CSV writer for it.
f = open(filename, 'wb')
writer = csv.writer(f)
# Process the header.
header = reader.next()
header.append('ID')
writer.writerow(header)
# Process each row of the body.
for row in reader:
row.append(filename)
writer.writerow(row)
# Close the file and we're done.
f.close()
# Run the function on all command-line arguments. Note that this does no
# checking for things such as file existence or permissions.
map(process_file, sys.argv[1:])
You can run this as follows:
blair#blair-eeepc:~$ python csv_add_filename.py file1.csv file2.csv
you can use fileinput to do in place editing
import sys
import glob
import fileinput
for filename in glob.glob(sys.argv[1]):
for line in fileinput.FileInput(filename,inplace=1) :
if fileinput.lineno()==1:
print line.rstrip() + " ID"
else
print line.rstrip() + "," + filename