Shell = Vérifier si la variable commence par #

16

je serais reconnaissant si vous pouviez m'aider à comprendre, à déterminer si le contenu d'une variable commence par le signe de hachage:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

cela ne fonctionne pas.

Merci!

Jans

Jan
la source
1
J'envisagerais la possibilité qu'il y ait aussi des espaces avant la balise de hachage lors du test des "commentaires", si c'est bien ce que vous faites.
rthomson
Comme vous avez accepté une réponse qui implique une bashsolution, vous pouvez peut-être modifier votre question, car cela implique que vous souhaitez une solution sh/ dash.
Charles Roberto Canato du
Je recommande d'utiliser un chemin absolu dans la #!ligne car un chemin relatif dans cette ligne est apparemment pris par rapport au répertoire actuel du processus exécutant le script plutôt que par rapport à l'emplacement du script.
kasperd

Réponses:

20

Votre approche originale fonctionnerait très bien si vous échappiez au hachage :

$ [[ '#snort' == \#* ]]; echo $?
0

Une autre approche serait de découper le premier caractère du contenu de la variable, en utilisant "Expansion de sous-chaîne":

if [[ ${x:0:1} == '#' ]]
then
    echo 'yep'
else
    echo 'nope'
fi

yep

Depuis la page de manuel de Bash:

   ${parameter:offset}
   ${parameter:offset:length}
          Substring  Expansion.   Expands  to  up  to length characters of
          parameter starting at the character  specified  by  offset.   If
          length  is omitted, expands to the substring of parameter start-
          ing at the character specified by offset.  length and offset are
          arithmetic   expressions   (see  ARITHMETIC  EVALUATION  below).
          length must evaluate to a number greater than or equal to  zero.
          If  offset  evaluates  to  a number less than zero, the value is
          used as an offset from the end of the value  of  parameter.   If
          parameter  is  @,  the  result  is  length positional parameters
          beginning at offset.  If parameter is an array name indexed by @
          or  *,  the  result is the length members of the array beginning
          with ${parameter[offset]}.  A negative offset is taken  relative
          to  one  greater  than the maximum index of the specified array.
          Note that a negative offset must be separated from the colon  by
          at  least  one  space to avoid being confused with the :- expan-
          sion.  Substring indexing is zero-based  unless  the  positional
          parameters are used, in which case the indexing starts at 1.
Insyte
la source
Pour voir cette page de manuel, je dois taper man what?
duleshi
C'est la page de manuel de Bash, " man bash" devrait le faire.
Insyte
2
C'est du bashisme, mais le tag parle de "shell" et non de "bash" :(.
pevik
11

Version compatible POSIX:

[ "${var%${var#?}}"x = '#x' ] && echo yes

ou:

[ "${var#\#}"x != "${var}x" ] && echo yes

ou:

case "$var" in
    \#*) echo yes ;;
    *) echo no ;;
esac
Kambus
la source
1
+1 pour la réponse posix. Dans certains tests de synchronisation rudimentaires, la caseméthode semble être la plus rapide des trois sur un ordinateur x86 32 bits assez ancien. Tous les trois sont bien plus efficaces qu'un simple exemple qui conduites à un processeur stdin fourchue comme: echo $var | cut -c1. Mon analyse était assez basique basée sur 10 000 000 itérations sur un seul ordinateur / système d'exploitation - YMMV. Je viens d'utiliser cet ordinateur plus lent pour exagérer les différences et les rendre plus visibles - au moins sur cette seule plateforme.
Juan
BTW, pour ces 10 000 000 itérations, les méthodes intégrées décrites dans cette réponse ont fonctionné en environ une minute (sur la boîte lente susmentionnée). La pipe à cutaromatiser a pris plus de 5 heures.
Juan
Et si vous voulez trouver des choses commençant par "
Justin
5

Je sais que cela peut être une hérésie, mais pour ce genre de choses, je préfère utiliser grep ou egrep plutôt que de le faire depuis l'intérieur du shell. C'est un peu plus cher (je suppose) mais pour moi, la lisibilité de cette solution compense cela. C'est une question de goût personnel, bien sûr.

Donc:

myvar="   #comment asfasfasdf"
if ! echo $myvar | egrep -q '^ *#'
then
  echo "not a comment"
else
  echo "commented out"
fi

Il fonctionne avec ou sans espaces principaux. Si vous souhaitez également prendre en compte les grands onglets, utilisez egrep -q '^ [\ t] * #' à la place.

Eduardo Ivanec
la source
En y réfléchissant peut-être, je préfère juste egrep parce que j'aime les expressions régulières, mais je considère que grep / egrep est utile dans un plus large éventail de situations de toute façon.
Eduardo Ivanec
0

Voici une autre façon ...

# assign to var the value of argument actual invocation
var=${1-"#default string"}

if [[ "$var" == "#"* ]]
then
  echo "$var starts with a #"
fi

Il suffit de copier-coller le contenu dans un fichier, d'accorder des autorisations d'exécution et de voir comment cela fonctionne;).

J'espère que cela aide!

Salutations.

Victor
la source
1
C'est du bashisme, mais le tag parle de "shell" et non de "bash" :(.
pevik