Mandalika's scratchpad [ Work blog @Oracle | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14  01.15  02.15  03.15  04.15  06.15  09.15  12.15  01.16  03.16  04.16  05.16  06.16  07.16  08.16  09.16  12.16  01.17  02.17  03.17  04.17  06.17  07.17  08.17  09.17  10.17  12.17  01.18  02.18  03.18  04.18  05.18  06.18  07.18  08.18  09.18  11.18  12.18  01.19  02.19  05.19  06.19  08.19  10.19  11.19  05.20  10.20  11.20  12.20  09.21  11.21  12.22 


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)

Labels:





2004-2019 

This page is powered by Blogger. Isn't yours?