Reputation: 75
In the assignment I have to do, I'm supposed to create an alternative to the 'rm' command. I have to pass variable number of arguments like ,
$ rm.py /path/to/some/file ./somefile someotherfile
$ rm.py /path/to/some/file ./somefile someotherfile -r
$ rm.py -r /path/to/some/file ./somefile someotherfile
$ rm.py *.java
the -r argument can be passed as any argument, at any place. the meaning of the -r is the same as in when using the regular 'rm' command. it recursively removes a directory and its contents within it.
it runs the script, and whichever path is given like
rm.py /path/to/some/file
it then moves that to the output directory '~/rm_trash' if there are duplicates, i worry about that as well.
But to start, I'm having some trouble understanding how to approach it. Should I go about it in a for loop, and if one of the arguments equals to the '-r' go from there?
Should i import and use argparse?
I have some more questions, but I'd like to first handle what I'm asking above.
Having to post again, still don't understand how I can get the specific argument for any number of argument besides the 'r'
Upvotes: 3
Views: 744
Reputation: 23556
Why not use:
os.system( 'rm ' + ' '.join( sys.argv[1:] )
and get it done.
Upvotes: 0
Reputation: 231665
Define a parsing function, which looks for the '-r' string:
def parse(alist, astr='-r'):
try:
idx = alist.index(astr)
r = alist.pop(idx)
return True, alist
except ValueError:
return False, alist
If we do
import sys
r, rest = parse(sys.argv[1:])
should give a True/False value for r
, and a list of file names. Use those in the rest of your code.
Testing:
In [326]: list1 = 'rm.py /path/to/some/file ./somefile someotherfile'.split()
In [329]: r, rest = parse(list1[1:])
In [330]: r, rest
Out[330]: (False, ['/path/to/some/file', './somefile', 'someotherfile'])
In [331]: list2 = 'rm.py /path/to/some/file ./somefile someotherfile -r'.split()
In [332]: r, rest = parse(list2[1:])
In [333]: r, rest
Out[333]: (True, ['/path/to/some/file', './somefile', 'someotherfile'])
To illustrate what happens when '-r' is present:
In [335]: list2.index('-r')
Out[335]: 4
In [336]: list2.pop(4)
Out[336]: '-r'
In [337]: list2
Out[337]: ['rm.py', '/path/to/some/file', './somefile', 'someotherfile']
if it isn't present we get a ValueError
:
In [338]: list1.index('-r')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-338-807fbe60be44> in <module>
----> 1 list1.index('-r')
ValueError: '-r' is not in list
======
The equivalent functionality using argparse
:
In [339]: import argparse
In [340]: parser = argparse.ArgumentParser()
In [341]: parser.add_argument('-r', action='store_true', help='recursive flag');
In [342]: parser.add_argument('rest', nargs='*', help='file names');
In [343]: args = parser.parse_args(list1[1:])
Use args = parser.parse_args()
to read the sys.argv
.
The result is a namespace
object that has the needed attributes:
In [344]: args
Out[344]: Namespace(r=False, rest=['/path/to/some/file', './somefile', 'someotherfile'])
In [345]: args.r
Out[345]: False
In [346]: args.rest
Out[346]: ['/path/to/some/file', './somefile', 'someotherfile']
Use args.r
and args.rest
in the same way as r
and rest
above.
The '-r' can be before or after the list of file names. argparse
becomes more useful when you want to define more options like '-r'. It also takes care of displaying a help message, and meaningful errors.
In [347]: parser.parse_args(['--help'])
usage: ipython3 [-h] [-r] [rest [rest ...]]
positional arguments:
rest file names
optional arguments:
-h, --help show this help message and exit
-r recursive flag
Upvotes: 1
Reputation: 4673
If you don't want to use argparse
, or cannot for purposes of an assignment, you could look inside sys.argv
:
is_recursive = any(arg == '-r' for arg in sys.argv)
# `paths` will be a list of all other arguments
paths = [arg for arg in sys.argv if arg != '-r']
Upvotes: 1
Reputation: 7224
I would use argparse, as you can specify out of order actions:
https://docs.python.org/3/library/argparse.html
Upvotes: 2