Shell = Проверить, начинается ли переменная с #

16

Я был бы благодарен, если бы вы могли помочь мне, как выяснить, как определить, начинается ли содержимое переменной со знака хеша:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

это не работает.

Благодарность!

Янс

январь
источник
1
Я бы рассмотрел возможность того, что перед хеш-тегом могут быть пробелы и при проверке на «комментарии», если это действительно то, что вы делаете.
rthomson
Поскольку вы приняли ответ, который включает bashрешение, возможно, вы могли бы отредактировать свой вопрос, поскольку это подразумевает, что вы желаете sh/ dashрешения.
Чарльз Роберто Канато
Я рекомендую использовать абсолютный путь в #!строке, поскольку относительный путь в этой строке, по-видимому, берется относительно текущего каталога процесса, выполняющего сценарий, а не относительно того, где расположен сценарий.
kasperd

Ответы:

20

Ваш оригинальный подход будет работать отлично, если вы избежите хеша :

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

Другим подходом было бы отрезать первый символ содержимого переменной, используя «Расширение подстроки»:

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

yep

Со страницы руководства 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
источник
Чтобы увидеть эту справочную страницу, я должен напечатать man что?
Дулеши
Это страница руководства Bash, так что " man bash" должен это сделать.
Insyte
2
Это bashism, но тег относится к "shell", а не к "bash" :(.
pevik
11

POSIX-совместимая версия:

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

или:

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

или:

case "$var" in
    \#*) echo yes ;;
    *) echo no ;;
esac
Kambus
источник
1
+1 за ответ posix. В некоторых элементарных временных тестах этот caseметод является самым быстрым из трех на довольно старом 32-битном компьютере x86. Все три являются гораздо более эффективным , чем простой пример , который труба с раздвоенным стандартным вводом процессора , как: echo $var | cut -c1. Мой анализ был довольно простым, основанным на 10 000 000 итераций на одном компьютере / компьютере - YMMV. Я использовал этот более медленный компьютер, чтобы преувеличивать любые различия и делать их более заметными - по крайней мере, на одной платформе.
Хуан
Кстати, для этих 10 000 000 итераций встроенные методы, описанные в этом ответе, выполнялись примерно за минуту (на вышеупомянутой медленной коробке). Труба до 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
Это bashism, но тег относится к "shell", а не к "bash" :(.
pevik