Linux Format

★ String bashing

-

Using Bash, I am trying to parse a string of undefined length to check whether the last five characters are correct, in particular whether the value of NAME does not yet have the dot extension “.epub” appended. It needs to cope if the string is shorter than the extension. Trying variations on the following – if [ ! NAME=*.epub ] – the endless variations on dollar prefixes, enclosing quotes, white space and doubleequa­ls in the Bash documentat­ion are driving me mental. Can you explain what is the correct way to do this and why? guy This is Linux! There is generally more than one correct way to do something, but several approaches, each with its own merits. You cannot use filename wildcards like this; they are interprete­d by the shell when referring to files. There are countless variants on using sed, awk or cut to process a string like this, but for what you want the built-in variable expansion of Bash will do the job.

If you have a variable called NAME and you want to check whether it has an epub extension, this test will do it: if [ "${NAME}" = "${NAME%.epub}" ] ; then ...

The % operator strips the following characters from the end of the variable, if possible. So mybook.epub becomes mybook while mybook is unchanged. The above test checks whether the % operator makes any changes to the variable and returns true if it does. If all you want to do is make sure the name has an extension of .epub, you could use this: NAME="${NAME%.epub}.epub" This strips any .epub extension and then adds one, so the name now has the extension, whatever its original value.

Bash has a number of useful operators like this. Using # instead of % removes the string from the start of the variable instead of the end. %% and ## are greedy versions of these, removing the longest possible match instead of the shortest. You can also do string replacemen­t anywhere in a variable like this: NEWNAME="${NAME/oldstr/newstr}" – rather like sed’s s operator. You can even specify default values for variables that may not have been defined, or set to null. ${NAME:-hello} returns the value of NAME if it is set, otherwise returns “hello”. Also, using = instead of - sets the variable to this value if it is unset.

Note that while the braces are optional for a simple variable usage – so $NAME is equivalent to ${NAME} – they are required when performing any form of substituti­on. Also, these operations are not unique to Bash and can be used even if your script uses the more universal /bin/sh.

Newspapers in English

Newspapers from Australia