Shell = Controlla se la variabile inizia con #


16

ti sarei grato se mi potessi aiutare come capire, come determinare se il contenuto di una variabile inizia con il segno hash:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

questo non funziona.

Grazie!

Jans


1
Considererei la possibilità che ci possano essere spazi anche prima del tag hash durante il test per "commenti", se è davvero quello che stai facendo.
rthomson,

Quando hai accettato una risposta che implica una bashsoluzione, forse potresti modificare la tua domanda, poiché implica che desideri una sh/ dashsoluzione.
Charles Roberto Canato,

Raccomando di usare un percorso assoluto nella #!riga poiché un percorso relativo in quella riga è apparentemente preso rispetto alla directory corrente del processo che esegue lo script piuttosto che rispetto a dove si trova lo script.
Kasperd,

Risposte:


20

Il tuo approccio originale funzionerebbe benissimo se sfuggissi all'hash :

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

Un altro approccio sarebbe tagliare il primo carattere del contenuto della variabile, usando "Espansione sottostringa":

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

yep

Dalla pagina man di 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.

Per vedere questa pagina man, dovrei digitare man what?
duleshi,

È la pagina man di Bash, quindi " man bash" dovrebbe farlo.
Insyte,

2
Questo è bashism, ma il tag riguarda "shell" e non "bash" :(.
pevik,

11

Versione compatibile POSIX:

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

o:

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

o:

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

1
+1 per la risposta posix. In alcuni test di temporizzazione rudimentale, il casemetodo sembra essere il più veloce dei tre su un computer x86 a 32 bit abbastanza vecchio. Tutti e tre sono di gran lunga più efficiente di un semplice esempio che i tubi ad un processore stdin biforcuta come: echo $var | cut -c1. La mia analisi era piuttosto semplice sulla base di 10.000.000 di iterazioni su un solo computer / sistema operativo - YMMV. Ho appena usato quel computer più lento per esagerare eventuali differenze e renderle più visibili, almeno su quella piattaforma.
Juan,

A proposito, per quelle 10.000.000 di iterazioni, i metodi integrati descritti in questa risposta sono stati eseguiti in circa un minuto (sulla casella lenta sopra menzionata). La pipa per cutaromatizzare ha impiegato 5+ ore.
Juan,

Che cosa succede se si desidera trovare le cose che iniziano con "
Justin

5

So che potrebbe essere un'eresia, ma per questo tipo di cose preferirei usare grep o egrep piuttosto che farlo all'interno della shell. È un po 'più costoso (immagino) ma per me la leggibilità di questa soluzione compensa quella. È una questione di gusti personali, ovviamente.

Così:

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

Funziona con o senza spazi iniziali. Se desideri tenere conto anche delle schede iniziali, usa invece egrep -q '^ [\ t] * #'.


Pensandoci forse preferisco egrep perché mi piacciono le regex, ma considero comunque grep / egrep utili in una disposizione più ampia delle situazioni.
Eduardo Ivanec,

0

Ecco un altro modo ...

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

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

Basta copiare incollare il contenuto in un file, concedere le autorizzazioni di esecuzione e vedere come funziona;).

Spero che sia d'aiuto!

Saluti.


1
Questo è bashism, ma il tag riguarda "shell" e non "bash" :(.
pevik,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.