1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Basic Shell Script with Sed Malfunctioning

  1. Mar 24, 2012 #1
    1. The problem statement, all variables and given/known data

    Write a bash shell script to do the following:

    # This shell script renames all files in the current
    # directory, removing all vowels in the names.
    # if the resultant name would lack any characters (excluding the extension)
    # The file is not renamed. Also does not attempt to rename files that have no vowels.

    2. Relevant equations

    None.

    3. The attempt at a solution
    I do not understand why this line of code doesn't work:

    Code (Text):
    new_name_no_ext=`echo $voweless_name | sed -e "s/\.[^\.]+$//"`
    The above line should assign to $new_name_no_ext the string $voweless_name, without an extension. I am quite positive that the regex used is correct.

    The entire program is:

    Code (Text):
    #!/usr/bin/bash

    # This shell script renames all files in the current
    # directory, removing all vowels in the names.
    # if the resultant name would lack any characters (excluding the extension)
    # The file is not renamed. Also does not attempt to rename files that have no vowels.

    for filename in *                                                               #Traverse all files in the current directory
    do        
           current_name=$filename                                                   #Get the filename
           voweless_name=`echo $current_name | sed -e "s/[aeiou]//g"`               #Substitute vowel for nothing using sed
           new_name_no_ext=`echo $voweless_name | sed -e "s/\.[^\.]+$//"`
           echo "$new_name_no_ext"
           #if [ `echo $voweless_name | sed -e "s/\.([^\.]+)$//"` != "" -a "$current_name" != "$voweless_name"  ]   #Rename iff the new nane is non-empty and is not identival to the curent name
           if [ "$new_name_no_ext" != "" -a "$current_name" != "$voweless_name"  ]  #Rename iff the new nane is non-empty and is not identival to the curent name
           then
            mv "$current_name" "$voweless_name"                                     #Do the actual renaming
           fi
    done
    Any idea as to what is wrong?

    Thanks in advance.
     
  2. jcsd
  3. Mar 25, 2012 #2

    nvn

    User Avatar
    Science Advisor
    Homework Helper

    sunmaz94: Instead of a plus sign, did you intend to use an asterisk (*)?
     
  4. Mar 25, 2012 #3
    Thanks for your response.

    No I believe I want a "+", as the regex quantifier for "one or more". That behavior is desirable for extension removal. Any other idea as to why this isn't working?
     
  5. Mar 25, 2012 #4

    nvn

    User Avatar
    Science Advisor
    Homework Helper

    sunmaz94: Can you echo $current_name, immediately after the first line in the do-block, and show us what it outputs?
     
  6. Mar 25, 2012 #5
    It just outputs the name of the file being traversed (ex. apple.txt, hello.txt, a.txt, and b.txt ...).

    Likewise, the vowel-less variable outputs the the name of the file being traversed without vowels (ex. appl.txt, hllo.txt,.txt, and b.txt ...).
     
  7. Mar 25, 2012 #6

    nvn

    User Avatar
    Science Advisor
    Homework Helper

    sunmaz94: Hint 1: Put a backslash before your plus sign, and see if that helps. Or, you can change your plus sign to an asterisk, if you wish.

    By the way, remove your second backslash. It is incorrect, and is matching backslash. (Or did you intend to match backslash, in this design?)
     
    Last edited: Mar 25, 2012
  8. Mar 25, 2012 #7
    Thanks! Both of those were my mistakes.
     
  9. Mar 25, 2012 #8
    I believe your original expression works if you use sed -r -e ... The "+" is part of the "extended" syntax, and you need the -r switch to use it.
     
  10. Mar 25, 2012 #9

    NascentOxygen

    User Avatar

    Staff: Mentor

    I'm seeing sed living up to its reputation! :frown:

    You can omit the -e almost universally here, I believe, so I have.

    $ echo appl.txt |sed -r "s/\.[^\.]+$//"
    appl
    $ echo appl.txt |sed -r "s/\.[^\.]\+$//"
    appl.txt
    $ echo appl.txt |sed "s/\.[^\.]\+$//"
    appl.txt
    $ echo appl.txt |sed "s/\.[^\.]+$//"
    appl.txt

    So -r was definitely needed above, and it didn't require \+

    But on another system, I find:

    # echo appl.txt |sed "s/\.[^\.]+$//"
    appl.txt
    # echo appl.txt |sed "s/\.[^\.]\+$//"
    appl
    # echo appl.txt |sed -r "s/\.[^\.]+$//"
    appl
    # echo appl.txt |sed -r "s/\.[^\.]\+$//"
    appl.txt

    Will work using \+ without the need for -r

    Such inconsistency! :frown:
     
  11. Mar 25, 2012 #10

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    And none of them work on my computer (OSX 10.6) with the shell that I prefer to use (tcsh). I need to change the double quotes to single quotes, and change the -r option to -E.

    This is the 21st century, not 1990. The arguments for using sed in lieu of more powerful and better suited tools such as perl or python are getting a bit weak. The only systems where you won't find perl, python, or both available from boot time will also have a very archaic and probably non-standard sed.
     
  12. Mar 26, 2012 #11

    nvn

    User Avatar
    Science Advisor
    Homework Helper

    Good catch. I missed that. I would say universally, unless you know of any exception. The -e is redundant, and unneeded, here. NascentOxygen, your first system seems weird. :biggrin: Your second system seems normal.
    Good point. Thanks for mentioning that.
    A logical name change, or so it might seem, since the -r option invokes ERE (extended regular expressions). However, destroying portability for something that makes no difference is highly illogical.
     
    Last edited: Mar 26, 2012
  13. Mar 26, 2012 #12

    NascentOxygen

    User Avatar

    Staff: Mentor

    If you are using bash or ksh, consider using the shell's much more efficient construct:

    Code (Text):
    new_name_no_ext=`${voweless_name%.?*}`
    You seemed to be insistent on the + for sed, so I think you'll need the ? here for the shell. (Try it with, and without.)
     
  14. Mar 26, 2012 #13

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    Portability? What portability are you talking about? That -r option to sed is Linux-specific. The -E option on my computer is OSX-specific.

    If you want to use sed portably you will only use the options -e, -f, and -n, and won't use extended regular expressions. Everything other option and the use of extended regular expressions is non-standard.

    True portability amongst UNIX systems such as OSX, AIX, and HP-UX and UNIX-like systems such as Linux is achieved by going to the lowest common denominator.
     
  15. Mar 28, 2012 #14

    nvn

    User Avatar
    Science Advisor
    Homework Helper

    D H: Thanks for the helpful information. I almost never use ERE. A BRE (basic regular expression) works just as well here.
     
    Last edited: Mar 28, 2012
  16. Mar 28, 2012 #15

    NascentOxygen

    User Avatar

    Staff: Mentor

    There should not be back quotes around the parameter, delete these. ` ... `
     
    Last edited: Mar 28, 2012
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Basic Shell Script with Sed Malfunctioning
  1. A shell script doubt (Replies: 5)

  2. Unix script problem (Replies: 1)

  3. Program vs Script (Replies: 10)

Loading...