シェル=変数が#で始まるかどうかを確認します


16

変数のコンテンツがハッシュ記号で始まるかどうかを判断する方法を理解するのに役立つなら、私は感謝します:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

これは動作しません。

ありがとう!

ヤンス


1
「コメント」をテストするとき、ハッシュタグの前にもスペースがある可能性があると考えます。
rthomson

bashソリューションに関連する回答を受け入れた場合、sh/ dashソリューションを希望していることを意味するため、質問を編集できます。
チャールズロベルトカナト

その#!行の絶対パスは、スクリプトが置かれている場所ではなく、スクリプトを実行しているプロセスの現在のディレクトリに関連しているように見えるため、絶対パスを使用することをお勧めします。
カスペルド

回答:


20

ハッシュエスケープした場合、元のアプローチはうまく機能します:

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

別のアプローチは、「サブストリング拡張」を使用して、変数のコンテンツの最初の文字をスライスすることです。

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

yep

Bashのmanページから:

   ${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.

このmanページを表示するには、man whatと入力する必要がありますか?
duleshi

これはBashのマニュアルページman bashです。
Insyte

2
それはバシズムですが、タグは「bash」ではなく「shell」に関するものです
。– pevik

11

POSIX互換バージョン:

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

または:

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

または:

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

1
posixの回答については+1。いくつかの初歩的なタイミングテストでは、このcase方法はかなり古い32ビットx86コンピューターで3つのうちで最速のようです。3つすべては、次のような分岐したstdinプロセッサにパイプする単純な例よりもはるかに効率的ですecho $var | cut -c1。私の分析は、たった1台のコンピューター/ OS(YMMV)での10,000,000回の反復に基づく非常に基本的なものでした。遅くなったコンピューターを使用して、違いを誇張し、それらをより見やすくしました-少なくともそのプラットフォームでは。
フアン

ところで、これらの10,000,000回の反復に対して、この回答で説明されている組み込みメソッドは約1分で実行されました(前述のスローボックスで)。cutフレーバーへのパイプは5時間以上かかりました。
フアン

「」で始まるものを見つけたい場合
ジャスティン

5

私はこれが異端かもしれないことを知っていますが、この種のことのためにシェル内からやるよりもむしろgrepまたはegrepを使いたいです。それはもう少し高価ですが(私は推測します)、私にとってこのソリューションの可読性はそれを相殺します。もちろん、それは個人的な好みの問題です。

そう:

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

先行スペースの有無にかかわらず機能します。先行タブも考慮する場合は、代わりにegrep -q '^ [\ t] *#'を使用します。


考えてみると、おそらく正規表現が好きなのでegrepを好むだけですが、とにかくgrep / egrepはより広い範囲の状況で役立つと考えています。
エドゥアルドイヴァネック

0

ここに別の方法があります...

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

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

コンテンツをコピーしてファイルに貼り付け、実行権限を付与し、その動作を確認してください;)。

それが役に立てば幸い!

ご挨拶。


1
それはバシズムですが、タグは「bash」ではなく「shell」に関するものです
。– pevik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.