-
Why doesn't this work?
I'm writing a simple script to change the file extension of a file. I won't lie, it's a homework assignment and I finally figured out how to get sed to behave in the way I expected but when running the program, I get: "Bad: modifier in $( )" if I specify a file that doesn't exist. How can I fix that? What I WANT to happen is that if the second argument is blank or the file doesn't exist, for it to go to the then portion of the if code.
Code:
#!/bin/tcsh \
set fileExt="$1"
set oldName="$2"
if (-r $oldName) then
set newName = `echo $oldName | sed 's/.$/'$fileExt/''`
mv $oldName $newName
else
echo $oldName: No such file
endif
-
Hmm, got it to work using bash, any reason why the above doesn't work using tcsh?
Code:
#!/bin/bash
fileExt="$1"
oldName="$2"
if test -r $oldName;
then
newName=`echo $oldName | sed 's/.$/'$fileExt'/'`
mv $oldName $newName
else
echo $oldName: No such file
fi
-
The tcsh version worked fine for me, though your regular expression doesn't replace the extension, it only replaces the last character. You need to escape the . if you want a literal . and look into grabbing everything after the last . in the file name.
The error you're getting is probably related to your use of the colon in the echo statement: https://www.google.com/search?q=tcsh...r+in+%24(+)%22.
EDIT: Bash has a much sexier way then your sed hack. Check out rule #6 here: http://bashcurescancer.com/10-steps-...l-scripts.html. Not sure if tcsh has an analog.
EDIT 2: You could leverage the word modifiers (the probably source of your error) to strip the old extension. Read the "History substitution" and "Variable substitution" sections of the tcsh man page. Lots of other good stuff in there too.
-
whoops, I hadn't realized that it only replaced a single character! how can I match everything after a pattern with tcsh? Wildcard "*" doesn't seem to work. Also, for this assignment it is required that we use SED
Edit: I'll check out the man page as suggested. If I can't figure it out, I'll post back
-
Looks like I figured it out:
Code:
#!/bin/bash \
fileExt="$1"
shift
for oldName in $*
do
if test -r $oldName;
then
newName=`echo $oldName | sed 's/[^\.]*$/'$fileExt'/'`
mv $oldName $newName >& err.out
else
echo $oldName: No such file
fi
done
Thanks for the help! This works as expected. I now need to go back through and check over the rest of it. We submit it through an "auto grader" tool that checks the script vigorously for many cases...
EDIT: Got it to work for all cases - Seems like that was insane. He said "test it" before submitting, I didn't think he'd cover so many cases!
Code:
#!/bin/bash \
fileExt="$1"
shift
oldName="$1"
#for oldName in $*
while test "$oldName" != "";
do
if test -r "$oldName";
then
newName=`echo $oldName | sed "s/[^\.]*$/$fileExt/"`
mv "$oldName" "$newName" >& err.out
else
echo $oldName: No such file
fi
shift
oldName="$1"
done
What have I learned here? You have to use double quotes for your shell variables that contain spaces instead of single quotes - or so it seemed here -. Seems like that was the biggie here. Aside from bash's ..........ing about whitespace in variable assignment... Seems really picky and sloppy to me.