0

I was taking an online assessment and I got the below question.

  • Create a script located at /usr/local/bin/set-file-extensions that will change the extension of all files in the directory /var/dump/files based on user input.
  • The script should support the option flag -E that will allow a user to pass a three character extension(.i.e log).
  • If a non three character extension is passed by the user, display the error "Invalid input. A three character extension is required." and exit with a status code of 19.
  • Once that file extension is received, the script should rename all files under the directory /var/dump/files with the given extension. I.e. A file named myfile should be renamed as myfile.log.
2
  • 1
    Code Review would be a better venue if you have a script performing such a specific task and want it reviewed. Commented Aug 20, 2014 at 21:20
  • @Gilles, thanks. I was thinking that the script that I had, satisfied the criteria mentioned in the question. But apparently, it has quiet few flaws as pointed out by Stephane. I should try and modify them and the reason for posting it here is, I like it better here :) Commented Aug 20, 2014 at 21:28

2 Answers 2

1

You didn't specify that it had to be a bash solution so here is a python solution. It takes into account that you require a 3 character extension. However it doesn't do much in the way of checking you wont break anything. It does check for directories and that you are only going to rename real files. This solution will require an -E option to be passed in.

edit:

If filename starts with a . (hidden file) ignore. With regards to symlinks, that might take a little more thought.

#!/usr/bin/env python import sys import argparse import re import os def main(): path = '/var/dump/files' parser = argparse.ArgumentParser() parser.add_argument('-E', help='three character extension(.i.e log)',\ type=str) args = parser.parse_args() if args.E: if not re.search(r'^[a-zA-Z]{3}$', args.E): print 'Invalid Input. A three character extenstion required: %s' % str(args.E) sys.exit(19) ext = '.'+str(args.E) else: print 'Invalid Input. A three character extenstion required' sys.exit(19) files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path,f))] for f in files: # ignore hidden files if f[0] == '.': continue name = f.split('.')[0] os.rename(os.path.join(path,f),os.path.join(path,name+ext)) if __name__ == "__main__": main() 

This solution the -E will be option, and use '.log' as a default. You could specify Required=True in the add_argument() to have it as a required option.

#!/usr/bin/env python import sys import argparse import re import os def main(): path = '/var/dump/files' parser = argparse.ArgumentParser() parser.add_argument('-E', help='three character extension(.i.e log)',\ type=str) args = parser.parse_args() if args.E: if not re.search(r'^[a-zA-Z]{3}$', args.E): print 'Invalid Input. A three character extenstion required: %s' % str(args.E) sys.exit(19) ext = '.'+str(args.E) else: ext = '.log' files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path,f))] for f in files: # ignore hidden files if f[0] == '.': continue name = f.split('.')[0] os.rename(os.path.join(path,f),os.path.join(path,name+ext)) if __name__ == "__main__": main() 
1
  • [a-zA-Z] matches an ASCII latin letter, not a character. Note that isfile checks for regular (or symlink to regular) files, not the other types of files. It will rename all the hidden files (.cvsignore, .foo.bar) to ext. Commented Aug 21, 2014 at 9:49
0

I ended up creating a script like below.

#!/bin/bash while [[ $# -ge 1 ]] do key="$1" shift case $key in -E) EXTENSION="$1" length=$(expr length "$EXTENSION") if [ $length != 3 ] then (exit 19); echo "Invalid Input. A three character extension is required. Exit status:$?" else for f in /var/dump/files/*; do mv -- "$f" "${f}.$EXTENSION" done fi shift ;; *) (exit 19); echo "Invalid Option selected. Exit status:$?" ;; esac done 

References

https://stackoverflow.com/a/14203146/1742825

8
  • Close, I believe that -E is an optional parameter. The OP stated as one of the conditions: "based on user input"....I see no user input being reqested but I do see the enforcement of the -E parameter. Agree it is an interpretation issue. Commented Aug 20, 2014 at 19:16
  • 2
    What about -Efoo. You should use getopts. Commented Aug 20, 2014 at 19:46
  • case $var in ???) or [ "${#var}" -eq 3 ] for var length. GNU expr gives you the length in bytes, not characters and has trouble for values like + or index... Commented Aug 20, 2014 at 19:50
  • You should validate all the arguments before starting the job. Commented Aug 20, 2014 at 19:50
  • * doesn't match all files, just the non-hidden ones. It also expands non-regular files like directories or sockets (the requirements are not clear on that). Commented Aug 20, 2014 at 19:51

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.