Pages

Saturday, November 27, 2021

Shell Scripting: Tidbits #4

[1] Check if a String Starts with Substring or a Wildcard Pattern

Reproducing from Advanced Bash-Scripting Guide -> Chapter 7. Tests.

The == comparison operator behaves differently within a double-brackets test than within single brackets.

[[ $a == z* ]]   # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

eg.,

% cat -n compare.sh
     1	#!/bin/bash
     2	
     3	echo "Wildcard matching"
     4	
     5	for name in rats star
     6	do
     7		[[ ${name} == st* ]] && echo ${name} starts with "st" \
     8	        	             || echo ${name} does not start with "st"
     9	done
    10	
    11	echo
    12	echo "Literal matching"
    13	
    14	for name in st* star
    15	do
    16		[[ ${name} == "st*" ]] && echo ${name} matches with "st*" \
    17	        	             || echo ${name} does not match with "st*"
    18	done

% ./compare.sh
Wildcard matching
rats does not start with st
star starts with st

Literal matching
st* matches with st*
star does not match with st*

[2] Floating-Point Arithmetic in Bash

Bash doesn't understand or support floating-point arithmetic; and assumes numbers containing a decimal point as strings. Following simple calculation shows incorrect result.

% let a=1/2
% echo $a
0

Rely on other tools such as bc, dc (calculators), sed, awk, python, perl, .. for floating-point arithmetic in bash.

eg.,

# bc
% bc <<< 'scale=2; 1/2'
.50

% a=$(bc <<< 'scale=2; 1/2')
% echo $a
.50

# perl
% echo print 1/2 | perl
0.5

# python
% echo 'print(1/2)' | python3
0.5

[3] Floating-Point Comparison in Bash

bash man page makes it clear that arithmetic evaluation is done in fixed-width integers so decimal/floating-point numbers need to rely on other tools such as bc for arithmetic evaluation (see previous tip).

Following examples highlight the problem with floating-point evaluation in bash. bash didn't have a problem with 1 < 2 comparision involving fixed-width integers but failed with an error when decimal numbers are involved in a similar comparison.

% echo $((1 > 2))
0

% echo $((1 < 2))
1

% echo $((1.0 < 2.0))
-bash: 1.0 < 2.0: syntax error: invalid arithmetic operator (error token is ".0 < 2.0")

Workaround or alternative is to rely on other tools. Following example performs the floating-point comparison with the help of bc (basic calculator).

% echo "(1.0 < 2.0)" | bc -l
1

% echo "(1.0 > 2.0)" | bc -l
0

[4] Multiline or Block Comments in Bash

I guess few examples are sufficient for this one.

# Example 1

: <<'ABC'
comment
comment
comment
ABC

# Example 2

: <<'EOF'
comment
comment
EOF

# Example 3

: '
comment
comment
'

# Example 4

<< '////'
comment
comment
////

Note that any line that starts with a colon (:) is a no-op. All the text between the delimiter identifier strings in heredoc will be redirected to a no-op command ("ABC" and "EOF" are delimiter identifiers in above examples 1 and 2). The space between colon and << is important and the string in quotes is equally important to stop the shell from expanding the variables and/or evaluating them.

(Source: stackoverflow)

No comments:

Post a Comment