разделить вывод svnversion в bash - PullRequest
0 голосов
/ 15 декабря 2009

У меня есть эта функция, она отлично работает, но я бы хотел переписать ее в bash. проблема в том, что я слишком мало знаю о том, что доступно в bash.

#!/usr/bin/python

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()

что мне хотелось бы, так это небольшая bash-функция, которую я могу вызвать и которая установит что-то (три переменные? Массив?), Которое я смогу использовать. если это массив, мне бы очень хотелось, чтобы он был фиксированного размера (3).

Ответы [ 3 ]

4 голосов
/ 15 декабря 2009

Это создает массив с именем "tuple" с тремя элементами:

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

Требуется Bash 3.2 или выше. Может работать в Bash> = 3 и <3.2. Не переносится на оболочку Борна, хотя может быть адаптирована для оболочки Корн или Z. </p>

ksh использует переменную массива .sh.match, например: ${.sh.match[1]}

zsh использует переменную массива match, например: ${match[1]} или вы можете сделать

setopt bashrematch ksharrays

чтобы он работал с версией Bash точно так же, как указано выше.

Замена скобок должна быть одинаковой для всех трех.

1 голос
/ 15 декабря 2009

Вы можете использовать эту подпрограмму

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"
0 голосов
/ 15 декабря 2009

Следующее решение сохраняет значения в массиве arr [], чтобы максимально точно соответствовать вашему исходному кортежу. После блока if-else-fi вы можете делать что угодно с arr [0], arr [1] и arr [2]. Я старался максимально соответствовать вашему посту (и комментарию). Кроме того, я позволил себе отправлять предупреждения и уведомления в STDERR, а не в STDOUT, думая, что вы, вероятно, захотите их разделить.

#!/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"

Результат без STDERR (отправлено в / dev / null)

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

Результат с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...