web-dev-qa-db-fra.com

Extraire le numéro de version du fichier dans le script Shell

J'essaie d'écrire un script bash qui incrémente le numéro de version qui est donné dans

{major}.{minor}.{revision}

Par exemple.

1.2.13

Existe-t-il un bon moyen d'extraire facilement ces 3 nombres en utilisant quelque chose comme sed ou awk de telle sorte que je puisse incrémenter le numéro de {révision} et sortir la chaîne de numéro de version complète.

34
Dougnukem
$ v=1.2.13
$ echo "${v%.*}.$((${v##*.}+1))"
1.2.14

$ v=11.1.2.3.0
$ echo "${v%.*}.$((${v##*.}+1))"
11.1.2.3.1

Voici comment cela fonctionne:

La chaîne est divisée en deux parties.

  • le premier contient tout sauf le dernier point et les caractères suivants: ${v%.*}
  • le second contient tout sauf tous les caractères jusqu'au dernier point: ${v##*.}

La première partie est imprimée telle quelle, suivie d'un point uni et la dernière partie incrémentée à l'aide de l'expansion arithmétique de Shell: $((x+1))

56
jlliagre

Pure Bash utilisant un tableau:

version='1.2.33'
a=( ${version//./ } )                   # replace points, split into array
((a[2]++))                              # increment revision (or other part)
version="${a[0]}.${a[1]}.${a[2]}"       # compose new version
35
Fritz G. Mehner

Je préfère la commande "couper" pour ce genre de choses

major=`echo $version | cut -d. -f1`
minor=`echo $version | cut -d. -f2`
revision=`echo $version | cut -d. -f3`
revision=`expr $revision + 1`

echo "$major.$minor.$revision"

Je sais que ce n'est pas le chemin le plus court, mais pour moi c'est le plus simple à comprendre et à lire ...

25
Eedoh

Encore une autre façon de Shell (montrant qu'il y a toujours plus d'une façon de s'enculer avec ce genre de choses ...):

$ echo 1.2.3 | ( IFS=".$IFS" ; read a b c && echo $a.$b.$((c + 1)) )
1.2.4

Donc, nous pouvons faire:

$ x=1.2.3
$ y=`echo $x | ( IFS=".$IFS" ; read a b c && echo $a.$b.$((c + 1)) )`
$ echo $y
1.2.4
8
Chris J

J'utilise le fractionnement de Word du Shell; quelque chose comme

oIFS="$IFS"
IFS=.
set -- $version
IFS="$oIFS"

bien que vous deviez faire attention aux numéros de version en général en raison des suffixes alphabétiques ou de date et d'autres bits incohérents. Après cela, les paramètres de position seront définis sur les composants de $version:

$1 = 1
$2 = 2
$3 = 13

($IFS est un ensemble de caractères uniques, pas une chaîne, donc cela ne fonctionnera pas avec un séparateur de champs à caractères multiples, bien que vous puissiez utiliser IFS=.- à répartir sur . ou -.)

6
geekosaur

Awk le rend assez simple:

echo "1.2.14" | awk -F \. {'print $1,$2, $3'} Imprimera 1 2 14.

flag -F spécifie le séparateur.

Si vous souhaitez enregistrer l'une des valeurs:

firstVariable=$(echo "1.2.14" | awk -F \. {'print $1'})

5
bbaja42

Inspiré par la réponse de jlliagre J'ai fait ma propre version qui prend en charge les numéros de version ayant juste une version principale donnée . La version de jlliagre fera 1 -> 1.2 au lieu de 2.

Celui-ci convient aux deux styles de numéros de version:

function increment_version()
    local VERSION="$1"

    local INCREMENTED_VERSION=
    if [[ "$VERSION" =~ .*\..* ]]; then
        INCREMENTED_VERSION="${VERSION%.*}.$((${VERSION##*.}+1))"
    else
        INCREMENTED_VERSION="$((${VERSION##*.}+1))"
    fi

    echo "$INCREMENTED_VERSION"
}

Cela produira les résultats suivants:

increment_version 1         -> 2 
increment_version 1.2       -> 1.3    
increment_version 1.2.9     -> 1.2.10 
increment_version 1.2.9.101 -> 1.2.9.102
1
Sven Driemecker

Petite variation sur la solution de fgm en utilisant la commande intégrée read pour diviser la chaîne en un tableau. Notez que la portée de la variable IFS est limitée à la commande read (donc pas besoin de stocker et de restaurer la variable IFS actuelle).

version='1.2.33'
IFS='.' read -r -a a <<<"$version"
((a[2]++))
printf '%s\n' "${a[@]}" | nl
version="${a[0]}.${a[1]}.${a[2]}"
echo "$version"

Voir: Comment diviser une chaîne sur un délimiteur dans Bash?

0
tylo