Shell = Überprüfen, ob die Variable mit # beginnt

16

Ich wäre dankbar, wenn Sie mir helfen könnten, herauszufinden, wie der Inhalt einer Variablen mit dem Hash-Zeichen beginnt:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

Das funktioniert nicht.

Vielen Dank!

Jans

jan
quelle
1
Ich würde die Möglichkeit in Betracht ziehen, dass es beim Testen auf "Kommentare" auch Leerzeichen vor dem Hash-Tag geben kann , wenn Sie das tatsächlich tun.
Rthomson
Da Sie eine Antwort akzeptiert haben, die eine bashLösung beinhaltet , können Sie Ihre Frage möglicherweise bearbeiten, da dies impliziert, dass Sie eine sh/ dash-Lösung wünschen .
Charles Roberto Canato
Ich empfehle, einen absoluten Pfad in der #!Zeile zu verwenden, da der relative Pfad in dieser Zeile anscheinend relativ zum aktuellen Verzeichnis des Prozesses ist, der das Skript ausführt, und nicht relativ zu dem Ort, an dem sich das Skript befindet.
Kasperd

Antworten:

20

Dein ursprünglicher Ansatz würde gut funktionieren, wenn du dem Hash entkommen würdest :

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

Ein anderer Ansatz wäre, das erste Zeichen des Variableninhalts mit "Substring Expansion" abzutrennen:

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

yep

Von der Bash-Manpage:

   ${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
quelle
Um diese Manpage zu sehen, sollte ich man was eingeben?
Duleshi
Es ist die Bash-Manpage, " man bash" also sollte es so sein.
Insyte
2
Das ist Bashismus, aber Tag geht es um "Shell" nicht "Bash" :(.
Pevik
11

POSIX-kompatible Version:

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

oder:

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

oder:

case "$var" in
    \#*) echo yes ;;
    *) echo no ;;
esac
Kambus
quelle
1
+1 für die Posix-Antwort. In einigen rudimentären Timing-Tests casescheint die Methode auf einem relativ alten 32-Bit-x86-Computer die schnellste zu sein. Alle drei sind weit effizienter als ein einfaches Beispiel , die Rohre zu einem gegabelten stdin Prozessor wie: echo $var | cut -c1. Meine Analyse war ziemlich einfach, basierend auf 10.000.000 Iterationen auf nur einem Computer / Betriebssystem - YMMV. Ich habe gerade diesen langsameren Computer verwendet, um Unterschiede zu übertreiben und sie sichtbarer zu machen - zumindest auf dieser einen Plattform.
Juan
Übrigens liefen die in dieser Antwort beschriebenen eingebauten Methoden für diese 10.000.000 Iterationen in etwa einer Minute (auf der oben erwähnten langsamen Box). Das Pfeifenaroma cutdauerte 5+ Stunden.
Juan
Was ist, wenn Sie Dinge finden möchten, die mit "
Justin
5

Ich weiß, dass dies vielleicht eine Irrlehre ist, aber für diese Art von Dingen würde ich lieber grep oder egrep verwenden, als es aus der Shell heraus zu tun. Es ist ein bisschen teurer (denke ich), aber für mich gleicht die Lesbarkeit dieser Lösung das aus. Es ist natürlich eine Frage des persönlichen Geschmacks.

So:

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

Es funktioniert mit oder ohne führende Leerzeichen. Wenn Sie auch führende Tabs berücksichtigen möchten, verwenden Sie stattdessen egrep -q '^ [\ t] * #'.

Eduardo Ivanec
quelle
Wenn ich darüber nachdenke, bevorzuge ich vielleicht egrep, weil ich reguläre Ausdrücke mag, aber ich halte grep / egrep sowieso für nützlich in einer größeren Anzahl von Situationen.
Eduardo Ivanec
0

Hier ist ein anderer Weg ...

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

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

Kopieren Sie einfach den Inhalt in eine Datei, erteilen Sie Ausführungsberechtigungen und sehen Sie, wie es einfach funktioniert;).

Ich hoffe es hilft!

Schöne Grüße.

Sieger
quelle
1
Das ist Bashismus, aber Tag geht es um "Shell" nicht "Bash" :(.
Pevik