Project

General

Profile

« Previous | Next » 

Revision 3774

expand_braces: Also expand XPaths containing [], with up to one level of nesting (which is the most we currently use), because many {} XPaths do in fact contain []. Debug-print intermediate values when env var expand_braces_debug is true. Added usage message.

View differences:

expand_braces
1 1
#!/bin/bash
2 2
# Expands bash-style {} expressions.
3 3
# See <http://www.gnu.org/software/bash/manual/bash.html#Brace-Expansion>.
4
# Usage: [env expand_braces_debug=1] self <in >out
4 5
# Filters each line from stdin to stdout.
5 6
# Warning: Due to shell limitations, a blank line will be interpreted as EOF.
6 7

  
......
10 11

  
11 12
echoEach () { local line; for line in "$@"; do echo "$line"; done; }
12 13

  
14
replaceRecursive ()
15
{
16
    local sedExpr="$1" str="$2" prevStr
17
    while true; do
18
        prevStr="$str"
19
        str="$(echo "$str"|sed -e "$sedExpr")"
20
        test "$str" = "$prevStr" && break # done if nothing replaced
21
    done
22
    echo "$str"
23
}
24

  
25
debug ()
26
{
27
    local label="$1" str="$2"
28
    test -n "$expand_braces_debug" && (echo "** $label:"; echo "$str") >&2
29
}
30

  
13 31
singleQuote="'"
14 32
singleQuoteEsc="'\''"
15 33
CR=$'\r'
16 34
LF=$'\n'
17
braceKeep='./{'
18
bracketKeep='{*[*,*]*}'
35
nonBracket="[^][]*" # matches non-[] chars
36
brackets="($nonBracket\[$nonBracket\])*$nonBracket"
19 37

  
20 38
while true; do
21 39
    read # get next line from stdin; strips trailing newlines
22 40
    line="$REPLY"
23 41
    test -z "$line" && break # EOF if no line or empty line
24 42
    
25
    if test "${line/$braceKeep/}" != "$line" \
26
-o "${line/$bracketKeep/}" != "$line"; then # line contains unparseable exprs
27
        echo "$line" # don't expand
28
    else
29
        line="${line//$CR/}" # remove \r
30
        line="${line//$singleQuote/$singleQuoteEsc}" # escape single quotes
31
        line="$(echo "$line"|sed -e "s/[^{,}]+/'&'/g")" # escape non-brace chars
32
        
33
        eval echoEach $line # brace-expand $line
34
    fi
43
    line="${line//$CR/}" # remove \r
44
    origLine="$line"
45
    debug orig "$line"
46
    
47
    line="${line//$singleQuote/$singleQuoteEsc}" # escape single quotes
48
    line="$(echo "$line"|sed -e "s/[^{,}]+/'&'/g")" # escape non-brace chars
49
    # Escape commas inside [], which should not be used for {}.
50
    # Note that '' around "," are closing and opening the escaped string,
51
    # not the other way around.
52
    line="$(replaceRecursive "s/(\[$nonBracket)','/\1,/g" "$line")" # innermost
53
    # Also support one level of nesting, which is the most we currently use.
54
    line="$(replaceRecursive "s/(\[$brackets)','/\1,/g" "$line")" # 1st outer
55
    debug escaped "$line"
56
    
57
    debug expanded
58
    eval echoEach $line # brace-expand $line
35 59
done

Also available in: Unified diff