44# We do some (incomplete) YAML parsing in bash as helper to 04-cloud-secret.sh
55# to extract and construct a conforming clouds.yaml with exactly one
66# openstack entry.
7- # This is SLOW by walking a file line by line, using several grep calls per line,
8- # which is a fork.
9- # Could be optimized by doing the simple things in bash, but this is not urgent .
7+ # This used to be SLOW by using several grep calls (forks) per line.
8+ # Optimized a bit using three helpers; still going line by line in bash, so expect
9+ # 2s for 1000 lines of clouds.yaml or so .
1010#
1111# (c) Kurt Garloff <s7n@garloff.de>, 5/2025
1212# SPDX-License-Identifier: CC-BY-SA-4.0
13- #
13+
14+ # linestart detection
15+ # $1: linestart to look for
16+ # $2: string to search in
17+ startswith ()
18+ {
19+ case " $2 " in
20+ " $1 " * )
21+ return 0;;
22+ esac
23+ return 1
24+ }
25+
26+ # emptyline helper
27+ # $1: line
28+ islineempty ()
29+ {
30+ local LN
31+ IFS=" " read LN < <( echo " $1 " )
32+ if test -z " $LN " ; then return 0; else return 1; fi
33+ }
34+
35+ # comment helper
36+ # $1: line
37+ islinecomment ()
38+ {
39+ local LN
40+ IFS=" " read LN < <( echo " $1 " )
41+ if test " ${LN: 0: 1} " = " #" ; then return 0; else return 1; fi
42+ }
43+
1444# Helper: Parse YAML (recursive)
1545#
1646# We take two parameters
@@ -36,17 +66,20 @@ extract_yaml_rec()
3666 while IFS=" " read line; do
3767 let LNNO+=1
3868 # Ignore empty lines
39- if echo " $line " | grep ' ^\s*$' > /dev/null 2>&1 ; then continue ; fi
69+ # if echo "$line" | grep -q '^\s*$'; then continue; fi
70+ if islineempty " $line " ; then continue ; fi
4071 # First line of new block: We need more indentation ...
4172 if test " $more " = " 1" ; then
42- if ! echo " $line " | grep " ^$previndent \s" > /dev/null 2>&1 ; then return ; fi
73+ if ! echo " $line " | grep -q " ^$previndent \s" ; then return ; fi
4374 more=$( echo " $line " | sed " s/^$previndent \\ (\s*\\ )[^\s].*\$ /\\ 1/" )
4475 # echo "$previndent$more# $LNNO: New indent level"
4576 fi
4677 # Detect less indentation than wanted, return
47- if ! echo " $line " | grep " ^$previndent$more " > /dev/null 2>&1 ; then return ; fi
78+ # if ! echo "$line" | grep -q "^$previndent$more"; then return; fi
79+ if ! startswith " $previndent$more " " $line " ; then return ; fi
4880 # Strip comments if requested
49- if test -n " $RMVCOMMENT " && echo " $line " | grep ' ^\s*#' > /dev/null 2>&1 ; then continue ; fi
81+ # if test -n "$RMVCOMMENT" && echo "$line" | grep -q '^\s*#'; then continue; fi
82+ if test -n " $RMVCOMMENT " && islinecomment " $line " ; then continue ; fi
5083 # OK, we we have at least the indentation level needed
5184 # 3 cases:
5285 # (a) We are prior to finding the right block, continue searching
@@ -58,21 +91,23 @@ extract_yaml_rec()
5891 # got here, just output until the less indentation clause above indicates the end
5992 if test -z " $1 " ; then
6093 # echo "$previndent$more# $LNNO: Outputing block"
61- if test -z " $REMOVE " || ! echo " $line " | grep " ^$previndent$more$REMOVE :" > /dev/null 2>&1 ; then
94+ # if test -z "$REMOVE" || ! echo "$line" | grep -q "^$previndent$more$REMOVE:"; then
95+ if test -z " $REMOVE " || ! startswith " $previndent$more$REMOVE :" " $line " ; then
6296 echo " $line "
6397 fi
6498 continue
6599 fi
66100 # b2: Search for the keyword
67- if echo " $line " | grep " ^$previndent$more $1 :" > /dev/null 2>&1 ; then
101+ # if echo "$line" | grep -q "^$previndent$more$1:"; then
102+ if startswith " $previndent$more $1 :" " $line " ; then
68103 # echo "$previndent$more# $LNNO: Found keyword $1"
69104 # Output tree unless we suppress it
70105 if test -z " $RMVTREE " ; then
71106 echo " $line "
72107 else
73108 # At the leaf, we may hold a value
74109 if test -z " $2 " ; then
75- echo " $line " | grep --color=never " ^$previndent$more $1 : [^\\ s]" 2> /dev/null
110+ echo " $line " | grep --color=never " ^$previndent$more $1 : [^\\ s]"
76111 fi
77112 fi
78113 shift
0 commit comments