getting file path from command line argument in python - python

Can anyone guide me how can I get file path if we pass file from command line argument and extract file also. In case we also need to check if the file exist into particular directory
python.py /home/abhishek/test.txt
get file path and check test.txt exist into abhishek folder.
I know it may be very easy but I am bit new to pytho

import os
import sys
fn = sys.argv[1]
if os.path.exists(fn):
print os.path.basename(fn)
# file exists

Starting with python 3.4 you can use argparse together with pathlib:
import argparse
from pathlib import Path
parser = argparse.ArgumentParser()
parser.add_argument("file_path", type=Path)
p = parser.parse_args()
print(p.file_path, type(p.file_path), p.file_path.exists())

I think the most elegant way is to use the ArgumentParser This way you even get the -h option that helps the user to figure out how to pass the arguments. I have also included an optional argument (--outputDirectory).
Now you can simply execute with python3 test.py /home/test.txt --outputDirectory /home/testDir/
import argparse
import sys
import os
def create_arg_parser():
# Creates and returns the ArgumentParser object
parser = argparse.ArgumentParser(description='Description of your app.')
parser.add_argument('inputDirectory',
help='Path to the input directory.')
parser.add_argument('--outputDirectory',
help='Path to the output that contains the resumes.')
return parser
if __name__ == "__main__":
arg_parser = create_arg_parser()
parsed_args = arg_parser.parse_args(sys.argv[1:])
if os.path.exists(parsed_args.inputDirectory):
print("File exist")

Use this:
import sys
import os
path = sys.argv[1]
# Check if path exits
if os.path.exists(path):
print "File exist"
# Get filename
print "filename : " + path.split("/")[-1]

Related

TypeError: listdir: path should be string, bytes, os.PathLike or None, not Namespace

I am using Python 3.9, PyCharm 2022.
My purpose (Ultimate goal of this question): create a command line application receive 2 parameters:
Path of directory
Extension of files
then get size of files (Per file size, not sum of files size).
import os
import argparse
from os import listdir
from os.path import isfile, join
def main():
parser = argparse.ArgumentParser()
parser.add_argument("path", help="Path of directory.")
parser.add_argument("ext", help="Extension of files (for example: jpg, png, exe, mp4, etc.")
args1 = parser.parse_args()
args2 = parser.parse_args()
print(args1)
arr = os.listdir(args1)
print(arr)
# os.path.getsize(args.path)
# bytes_size = os.path.getsize(args1.path)
# mb_size = int(bytes_size / 1024 / 1024)
# print(mb_size, "MB")
if __name__ == '__main__':
main()
My command and according error:
(base) PS C:\Users\donhu\PycharmProjects\pythonProject4> python size.py 'D:' 'jpg'
Traceback (most recent call last):
File "C:\Users\donhu\PycharmProjects\pythonProject4\size.py", line 22, in <module>
(base) PS C:\Users\donhu\PycharmProjects\pythonProject4> python size.py 'D:' 'jpg'
Namespace(path='D:', ext='jpg')
Traceback (most recent call last):
File "C:\Users\donhu\PycharmProjects\pythonProject4\size.py", line 23, in <module>
main()
File "C:\Users\donhu\PycharmProjects\pythonProject4\size.py", line 13, in main
arr = os.listdir(args1)
TypeError: listdir: path should be string, bytes, os.PathLike or None, not Namespace
(base) PS C:\Users\donhu\PycharmProjects\pythonProject4>
How to fix?
Update, I tried something
import os
import argparse
from os import listdir
from os.path import isfile, join
from pathlib import *
def main():
parser = argparse.ArgumentParser()
parser.add_argument("path", help="Đường dẫn của thư mục")
parser.add_argument("ext", help="Định dạng tập tin cần liệt kê kích thước.")
args1 = parser.parse_args()
args2 = parser.parse_args()
foo = args1.path
# arr = os.listdir('D:/')
files = [x for x in foo.iterdir() if x.is_file()]
print(files)
# os.path.getsize(args.path)
# bytes_size = os.path.getsize(args1.path)
# mb_size = int(bytes_size / 1024 / 1024)
# print(mb_size, "MB")
if __name__ == '__main__':
main()
but not work.
The os module holds the traditional interface into the file system. It closely follows the Clib interface so you'll see functions like listdir and stat. pathlib is a new object oriented "pythonic" interface to the file system. One can argue whether its better, but I use it, so its gotta be, right?
It looks like you are mixing "old" and "new" ways of doing things, which gets confusing. If you want to use pathlib, try to use it for everything.
Here is your script re-imagined for pathlib. You only need to parse the command line once and then build a Path object for the directory of interest.
import argparse
from pathlib import Path
def main():
parser = argparse.ArgumentParser()
parser.add_argument("path", help="Đường dẫn của thư mục")
parser.add_argument("ext", help="Định dạng tập tin cần liệt kê kích thước.")
args = parser.parse_args()
foo = Path(args.path)
if not foo.is_dir():
print("Error: Must be a directory")
exit(1)
files = [x for x in foo.iterdir() if x.is_file()]
print(files)
# os.path.getsize(args.path)
bytes_size = sum(file.stat().st_size for file in files)
print("total bytes", bytes_size)
# mb_size = int(bytes_size / 1024 / 1024)
# print(mb_size, "MB")
if __name__ == '__main__':
main()
If you want to use the ext parameter, you would change from iterdir to glob.
files = [x for x in foo.glob(f"*.{args.ext}") if x.is_file()]
or
files = [x for x in foo.glob(f"**/*.{args.ext}") if x.is_file()]
depending on whether you want just the directory or its subtree.
Argparse's parse_args() function returns a Namespace object. I believe your goal was to pass the path argument, you have to access it as an attribute.
os.listdir(args1.path)
Program
import os
import argparse
from pathlib import Path
def main():
parser = argparse.ArgumentParser()
parser.add_argument("path", help="Path of directory/folder")
parser.add_argument("ext", help="Extension of file what need get size.")
args = parser.parse_args()
foo = Path(args.path)
files = [x for x in foo.glob(f"*.{args.ext}") if x.is_file()]
for file in files:
print(file.__str__(), os.path.getsize(file))
if __name__ == '__main__':
main()
# python size.py "D:\" 'jpg'
# (base) PS C:\Users\donhu\PycharmProjects\pythonProject4> python size.py "D:\" 'jpg'
# D:\1496231_10152440570407564_3432420_o.jpg 241439
# D:\15002366_278058419262140_505451777021235_o.jpg 598063
# D:\1958485_703442046353041_1444502_n.jpg 63839
# D:\277522952_5065319530178162_680264454398630_n.jpg 335423
Your two command line arguments are being returned as a single object of the argparse.Namespace class, both stored identically in your args1 and (the superfluous) args2 variables.
Inserting the following line after your calls to parse_args() and commenting out the subsequent code would illuminate this a little more:
print(type(args1))
To access the values you named in your calls to add_argument(), use this syntax:
args1.path
args1.ext
such as
arr = os.listdir(args1.path)
For further discussion, see this answer: Accessing argument values for argparse in Python

Delete a specific folder with a path as a parameter in python

I want to delete a Folder named "testfolder" and all the subfolders and files in it. I want to give the "testfolder" path as a parameter when calling the python file. For example ...... (testfolder location) and there it should delete the "testfolder" when the folder exists
I guess this might be what you're looking for
import os
import shutil
pathLocation = # Whatever your path location is
if os.path.exists(pathLocation):
shutil.rmtree(pathLocation)
else:
print('the path doesn\'t exist')
You can use shutil.rmtree() for removing folders and argparse to get parameters.
import shutil
import argparse
import os
def remove_folder(folder_path='./testfolder/'):
if os.path.exists(folder_path):
shutil.rmtree(folder_path)
print(f'{folder_path} and its subfolders are removed succesfully.')
else:
print(f'There is no such folder like {folder_path}')
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Python Folder Remover')
parser.add_argument('--remove', '-r', metavar='path', required=True)
args = parser.parse_args()
if args.remove:
remove_folder(args.remove)
You can save above script as 'remove.py' and call it from command prompt like:
python remove.py --remove "testfolder"
Better to use absolute path and import only the rmtree function from shutil import rmtree as this is a large package the above line will only import the required function.
from shutil import rmtree
rmtree('directory-absolute-path')

Python glob: how input directories and single files

This is an easy question.
I'm using glob to print the full hierarchy of a folder using this code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import argparse
import sys
import glob
parser = argparse.ArgumentParser()
parser.add_argument('-input', dest='input',help="input one or more files",metavar=None)
args = parser.parse_args()
def dirlist(path):
for i in glob.glob(os.path.join(path, "*")):
if os.path.isfile(i):
print (i)
elif os.path.isdir(i):
dirname = os.path.basename(i)
dirlist(i)
path = os.path.normpath(args.input)
dirlist(path)
It works pretty well, you just need to run python3 Test.py -input ..
As you can see by the argparse help description I would like to input directories but also single files.
I don't think this can be done using glob, is that right?
Can you suggest me a library that could help me print the full hierarchy of both directories and files?
I found here a long list of globe examples but they all seems to work for directories, not when you input a single file
Is nearly midnight but at least I found the solution after 2 days:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import argparse
import sys
import glob
parser = argparse.ArgumentParser()
parser.add_argument('-input', dest='input',help="input one or more files",metavar=None)
args = parser.parse_args()
def dirlist(path):
if os.path.isfile(path):
print (path)
elif os.path.isdir(path):
for i in glob.glob(os.path.join(path, "*")):
if os.path.isfile(i):
print (i)
elif os.path.isdir(i):
dirname = os.path.basename(i)
dirlist(i)
path = os.path.normpath(args.input)
dirlist(path)

Getting file path from command line arguments in python

I would like to read a file path from command line arguments, using argparse. Is there any optimal way to check if the path is relative (file is in current directory) or the complete path is given? (Other than checking the input and adding current directory to file name if the path does not exist.)
As Display Name said, os.path.isabs along with sys.argv is probably the best:
import sys
import os
fpath = sys.argv[-1]
print(os.path.isabs(fpath))
print(fpath)
output
>>>
True
C:\Users\310176421\Desktop\Python\print.py
>>>
some cmd stuff
C:\Users\310176421\Desktop\Python>python print.py C:\Users\310176421\Desktop\tes
t.txt
True
C:\Users\310176421\Desktop\test.txt
C:\Users\310176421\Desktop\Python>python print.py whatever
False
whatever

Using argparse, how can I put the user input into a list?

I need the file path and os.path.dirname does not give me the complete path (it does not include the file itself - e.g. home/a/b instead of home/a/b/filename). Also I need the file name so that I can print it later. Since the argument the user inputs IS the filename, I need a way to store the input into a list.
import sys
import argparse
import inspect, os
import os.path
file_list = []
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('file', type=argparse.FileType('r'), nargs='*')
args = parser.parse_args()
for f in args.file:
with f:
data = f.read()
print data
x = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
print x
file_list.append(x+#I need the filename here)
You can use os.path.abspath(f.name) to get the absolute filepath that was used to open the file f.
However, if you also want the filepath, it may be cleaner to just not convert the type to a fileobject, and do this yourself later, instead of trying to reverse-engineer where the open file came from. This way you will already have the list of filepaths, e.g.:
file_list = []
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='*')
args = parser.parse_args()
for filepath in args.file:
x = os.path.abspath(filepath)
with open(filepath, 'r') as f:
data = f.read()
print data
file_list.append(x)
You can get the full path of a file handler using os.path.abspath(fl.name),
so this should work:
import sys
import argparse
import inspect, os
import os.path
file_list = []
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('file', type=argparse.FileType('r'), nargs='*')
args = parser.parse_args()
for f in args.file:
with f:
data = f.read()
print data
full_path = os.path.abspath(f)
file_list.append(full_path)
For future reference also notice os.path.basename which returns only the name component of a path.
How about
os.path.realpath(f.name)
That combines the current curpwd with the file name as recorded in f.name.
If that isn't robust enough, you could accept the filename from the user, and open the file yourself. FileType is not essential. It's just a convenience type, most useful in scripts that take input and output files and do something simple with them. In other words, scripts that immitate common bash functions.

Categories

Resources