Shell = Verifique se a variável começa com #


16

eu ficaria muito grato se você pudesse me ajudar a descobrir, como determinar se o conteúdo de uma variável começa com o sinal de hash:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

isso não funciona.

Obrigado!

Jans


11
Eu consideraria a possibilidade de que também haja espaços antes da tag hash ao testar "comentários", se é isso que você está fazendo.
Rdomson

Como você aceitou uma resposta que envolve uma bashsolução, talvez você possa editar sua pergunta, pois isso implica que você deseja uma sh/ dashsolução.
Charles Roberto Canato

Eu recomendo o uso de um caminho absoluto na #!linha, pois um caminho relativo nessa linha é aparentemente usado em relação ao diretório atual do processo que executa o script, e não em relação à localização do script.
Kasperd

Respostas:


20

Sua abordagem original funcionaria bem se você escapasse do hash :

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

Outra abordagem seria cortar o primeiro caractere do conteúdo da variável, usando "Expansão de Substring":

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

yep

Na página do manual do 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.

Para ver esta página de manual, devo digitar man what?
duleshi

É a página de manual do Bash, então " man bash" deve fazê-lo.
Insyte 31/03

2
Aquela Bashismo, mas tag é sobre "shell" não "bash" :(.
pevik

11

Versão compatível com POSIX:

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

ou:

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

ou:

case "$var" in
    \#*) echo yes ;;
    *) echo no ;;
esac

11
+1 para a resposta posix. Em alguns testes de cronometragem rudimentares, o casemétodo parece ser o mais rápido dos três em um computador x86 de 32 bits bastante antigo. Todos os três são muito mais eficiente do que um exemplo simples que tubos para um processador stdin bifurcada como: echo $var | cut -c1. Minha análise foi bastante básica, com base em 10.000.000 de iterações em apenas um computador / os - YMMV. Acabei de usar esse computador mais lento para exagerar as diferenças e torná-las mais visíveis - pelo menos nessa plataforma.
313 Juan Juan

BTW, para essas 10.000.000 iterações, os métodos internos descritos nesta resposta foram executados em cerca de um minuto (na caixa lenta acima mencionada). O tubo a cutsabor levou mais de 5 horas.
Juan Juan

E se você quiser encontrar coisas que começam com "
Justin

5

Eu sei que isso pode ser heresia, mas para esse tipo de coisa eu prefiro usar grep ou egrep ao invés de fazê-lo de dentro do shell. É um pouco mais caro (eu acho), mas para mim a legibilidade desta solução compensa isso. É uma questão de gosto pessoal, é claro.

Então:

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

Funciona com ou sem espaços à esquerda. Se você também deseja contabilizar as guias principais, use egrep -q '^ [\ t] * #'.


Pensando nisso, talvez eu prefira o egrep porque gosto de expressões regulares, mas considero que o grep / egrep seja útil em um conjunto mais amplo de situações.
Eduardo Ivanec

0

Aqui está outra maneira ...

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

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

Basta copiar e colar o conteúdo em um arquivo, conceder permissões de execução e observar como ele funciona;).

Espero que ajude!

Saudações.


11
Aquela Bashismo, mas tag é sobre "shell" não "bash" :(.
pevik
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.