web-dev-qa-db-fra.com

commande couper à l'intérieur si l'instruction échoue

Dans un script bash, j'ai une instruction if. Cette instruction évalue si une partie spécifique d'une chaîne (contenue dans une variable) est égale à une autre chaîne. J'utilise une commande cut pour isoler la partie de chaîne que je souhaite comparer. J'ai essayé quelques options différentes mais c'est celle-ci qui, à mon avis, devrait fonctionner. mais ce n'est pas le cas:

Disons que $VAR1 = "ABCDEFGHIJKLMN.csv"

if [ "$VAR1"| cut -c 7-18 = "GHIJKLMN.csv" ]; then
..do stuff..

Juste pour être sûr que j'ai testé la sortie de "$VAR1"| cut -c 7-18 et qu'il en résulte exactement la même chaîne que celle à laquelle je le compare.

Quelqu'un at-il une idée pourquoi cela ne fonctionnera pas?

3
matv1
if [ "$VAR1"| cut -c 7-18 = "GHIJKLMN.csv" ]; then

Cela permet d'exécuter [ "$VAR1" et de diriger le résultat vers cut -c 7-18 = "GHIJKLMN.csv" ]. [ échouera car son dernier argument sera ], et cut échouera car probablement ni = ni ] ne sont des fichiers.

Je vais deviner ce que tu voulais:

if [ "$(echo "$VAR1" | cut -c 7-18)" = "GHIJKLMN.csv" ]; then

Remarquez comment j'emballe la commande dans "$()". Cela le fait exécuter et remplace sa place par la sortie. Les citations sont importantes. Par conséquent, la sortie n'est pas divisée en plusieurs arguments pour [.

Suivant ce que je crois être les meilleures pratiques pour bash, je recommanderais plutôt de procéder ainsi:

if [[ "$(cut -c 7-18 <<< "$VAR1")" = "GHIJKLMN.csv" ]]; then

Cela évite une interprétation particulière de $VAR1 par echo (en fonction du contenu, cela pourrait être confondu avec les options) et l'appel de 2 exécutables inutiles, [ et echo. Quelque chose de spécial à noter ici est que vous n'avez pas vraiment besoin des citations que j'ai utilisées. [[ est une syntaxe spéciale de bash, et même si la substitution avait des espaces, bash ne le diviserait pas par Word. Cela ne diviserait pas non plus ce qui a été donné à <<<. GHIJKLMN.csv n'a pas d'espaces ni de caractères spéciaux, donc tout irait bien. En cas de doute, c’est une bonne habitude de tout citer.

Vous auriez pu également ignorer l'appel à cut en procédant comme suit:

if [[ "${VAR1:6:12}" = "GHIJKLMN.csv" ]]; then

Maintenant, tout se fait en bash sans exécuter aucun autre programme. Dans cette syntaxe, au lieu de donner à cut la plage de caractères que vous souhaitez, comme vous l'avez fait, vous fournissez le décalage basé sur 0 sur le premier caractère et le nombre de caractères souhaité. C'est 7 - 1 parce que les indices de cut commencent par 1, et 12 parce que l'intervalle 7-18 est inclusif, donc 18 - 7 + 1.

Je viens de voir que votre $VAR1 est "ABCDEFGHIJKLMN.csv". Puisque vous avez coupé à la fin, vous n'avez pas vraiment besoin de spécifier le nombre:

if [[ "${VAR1:6}" = "GHIJKLMN.csv" ]]; then
6
JoL

Cela marche:

#!/bin/bash

echo 'Beginning of script'
VAR1='ABCDEFGHIJKLMN.csv'
if [ $(echo "$VAR1" | cut -c 7-18) == "GHIJKLMN.csv" ]; then
    echo 'If condition triggered.'
fi
echo 'End of script'

Cela fonctionne aussi:

#!/bin/bash

echo 'Beginning of script'
VAR1='ABCDEFGHIJKLMN.csv'
VAR2=$(echo "$VAR1" | cut -c 7-18)
if [ "$VAR2" == "GHIJKLMN.csv" ]; then
    echo 'If condition triggered.'
fi
echo 'End of script'
2
Kevin Li