Quote:
Originally Posted by
tempestas
Hello,
Thanks SO much! It does work!
Unfortunately, I don't understand every step. May I ask for explanations?
In particular: IAm=${0##*/}
I have never seen this. If I echo $IAm the output is the name of the script that is called by the list, i.e. "rename.sh". What are the ##*/ meaning? 0 marks the argument from the list, right?
The other thing I don't get are the exits exit 2; exit 3; exit 4. Why are they numbered?
lastname="${2%%_*}"
2 again stands for the argument, right? What is the %%_* saying?
ymd="${3:6}${3:3:2}${3:0:2}"
First, I thought I understood for the day that the first number in the brackets {3:0:2} refers to the argument from the list, and 0:2 means the first 2 characters of the argument. But this logic does not seem to work on {3:3:2} and {3:6}. What is the logic behind?
And last but not least, the if statements and the counter.
if [[ ! -e "xx_EV_${lastname}.pdf" ]]
asks if the correct named file already exists, i.e. this is to circumvent that an already processed file is overwritten, correct? Why do you use -e instead of -f? What is the advantage?
And the counter. Why is it set to "1" but never tested again? I always thought you would use a counter in order to test whether it is less than or greater than and make it part of the if condition.
Sorry for asking so many questions. But I would like to understand how the script works so that for next purpose I know better where to start.
Thank you SO much again!
tempestas
Never apologize for asking questions! We want to help you learn. I'm glad it is working for you. Here are my responses with a little more detail than CarloM provided. I hope it helps.
Yes,
$0 is the pathname used to invoke your script. So, it could be
rename.sh,
./rename.sh,
../scripts/rename.sh, or lots of other strings.
IAm=${0##*/} removes the longest string from the
start of the expansion of
$0 that matches the pattern
*/. So, if your script was invoked using any of the above pathnames, IAm will be set to
rename.sh. You will note that $IAm is used as the 1st string printed as part of any diagnostic messages. It is a convention used to make it easy to figure out which script generated an error message.
When a script completes successfully, it should almost always exit with a zero exit value. When a script completes unsuccessfully, it should exit with a non-zero exit value. Using different non-zero values sometimes help find the line where a problem was detected. (After a shell script completes, its exit status can be seen by looking at the output from the command
echo $?.)
lastname="${2%%_*}" is very similar to
IAm=${0##*/}, but sets
lastname to the expansion of the 2nd command line argument with longest string at the
end matching the pattern
_* removed. So, if
$2 is
last_first or
last_first_middle,
$lastname will be set to
last.
Assume the 3rd command line argument is
20.02.2013. The
${3:start:length} expands to the substring of $3 whose first character is at position
start (numbered from 0) and contains up to
length characters. If
:length is omitted, the remainder of the string starting at position
start is used. So, in this example,
${3:6} expands to
2013,
${3:3:2} expands to
02, and
${3:0:2} expands to
20.
Yes,
test -e filename evaluates to true if a file of
any type is currently named
filename.
test -f filename evaluates to true if a
regular file is currently named
filename. I didn't want the renaming process to overwrite any existing file so I used -e instead of -f.
Note that I set ec (an abbreviation for
exit
code) to 0 before starting the for loop. After the loop terminates, the exit returned by this script is
$ec. If any moves were skipped because they would have overwritten an existing file, ec is set to 1. In this case the exit code will be 0 if all files were moved successfully and will return 1 if one or more files were not moved. (Obviously, you should also check the exit status of the move commands and set ec to 1 if any move failed; but I'll leave that as an exercise for the reader.) The script could have exited at the time it decided not to move a file, but with something like this I like it to do as much as it can, print a diagnostic for each failure, and return a non-zero exit status if any problems were found.