开发者

split svnversion output in bash

I have this function, works fine, but I would like to rewrite it in bash. the problem is, I have too little knowledge of what's available in bash.

#!/usr/bin/开发者_如何学JAVApython

def parse_svnversion(value):
    """split the output of svnversion into its three components

    given a string that looks like the output of the command
    svnversion, returns the 3-tuple (low, high, flags)

    >>> parse_svnversion('1024')
    (1024, 1024, '')
    >>> parse_svnversion('1024:2000')
    (1024, 2000, '')
    >>> parse_svnversion('1024M')
    (1024, 1024, 'M')
    >>> parse_svnversion('1024:2000MP')
    (1024, 2000, 'MP')
    """

    values = filter(lambda x: x.isdigit() or x==':', value).split(':')
    return int(values[0]), int(values[-1]), filter(str.isalpha, value)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

what I would like is a similarly small bash function that I can invoke and that will set something (three variables? an array?) that I can use. if it's an array, I would really like it to be of fixed size (3).


This creates an array called "tuple" with three elements:

[[ $(svnversion .) =~ ([0-9]+):*([0-9]*)([A-Z]*) ]]
tuple[0]=${BASH_REMATCH[1]}
tuple[1]=${BASH_REMATCH[2]:-${tuple[0]}}
tuple[2]=${BASH_REMATCH[3]:-''}

Requires Bash 3.2 or greater. It may work in Bash >= 3 and < 3.2. Not portable to the Bourne shell, although it can be adapted for the Korn shell or the Z shell.

ksh uses the .sh.match array variable, for example: ${.sh.match[1]}

zsh uses the match array variable, for example: ${match[1]} or you can do

setopt bashrematch ksharrays

to have it work with the Bash version exactly as above.

The brace substitutions should be the same for all three.


you can use this subroutine

parsesvn(){
 toparse="$1"
 num=${toparse%%[A-Z]*}
 alpha=${toparse##*[0-9]}
 IFS=":"
 set -- $num
 for i in $@
 do
    printf "%s " $i
 done
 if [ ! -z "$alpha" ];then
    printf "%s" "$alpha"
 fi
}

# main #
var=$(parsesvn "1024:2000")
set -- $var
if [ "$1" -lt "$2" ];then
    echo "ok"
    greater=$2
else
    echo "LHS: $1 greater than RHS: $2"
fi
echo "greater is $greater"


The following solution stores the values into the array arr[ ] to match your original tuple as closely as possible. After the if-else-fi block you can do whatever you want with arr[0],arr[1], and arr[2]. I tried to match your post (and comment) as closely as possible. Also, I took the liberty to send the warning and notice messages to STDERR rather than STDOUT thinking you probably want to separate those.

#!/bin/bash

parse_svnversion()
{
    if [[ "$1" = *:* ]]; then
        arr[0]=${1%:*}
        arr[2]=${1//[0-9:]/}
        tmp_arr[1]=${1#*:}
        arr[1]=${tmp_arr[1]//${arr[2]}/}
    else
        arr[2]=${1//[0-9:]/}
        arr[0]=${1//${arr[2]}/}
        arr[1]=${arr[0]}
    fi

    echo ${arr[@]} 

    head_rev=$( (( ${arr[0]} > ${arr[1]} )) && echo ${arr[0]} || echo ${arr[1]} )
    echo "Notice: head revision is $head_rev" >&2

    if (( ${arr[1]} < ${arr[0]} )); then
        echo "Warning: you're working with mixed revisions" >&2
    fi
    if [[ -n ${arr[2]} ]]; then
        echo "Warning: there are flags" >&2
    fi
}

parse_svnversion "1024"
parse_svnversion "1024:2000"
parse_svnversion "1024M"
parse_svnversion "1024:2000MP"
parse_svnversion "2000:1024M"

Result without STDERR (sent to /dev/null)

$ ./svn_split.sh 2> /dev/null
1024 1024
1024 2000
1024 1024 M
1024 2000 MP
2000 1024 M

Result with STDERR

$ ./svn_split.sh
1024 1024
Notice: head revision is 1024
1024 2000
Notice: head revision is 2000
1024 1024 M
Notice: head revision is 1024
Warning: there are flags
1024 2000 MP
Notice: head revision is 2000
Warning: there are flags
2000 1024 M
Notice: head revision is 2000
Warning: you're working with mixed revisions
Warning: there are flags
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜