Shell =检查变量是否以#开头


16

如果您能帮助我如何弄清楚,如何确定变量的内容是否以井号开头,我将不胜感激:

#!bin/sh    

myvar="#comment asfasfasdf"

if [ myvar = #* ] 

这行不通。

谢谢!

扬斯


1
我会考虑是否有可能在测试“评论”时在hash标记之前也有空格,如果确实如此。
rthomson 2011年

当您接受涉及bash解决方案的答案时,也许您可​​以编辑您的问题,因为这暗示您希望获得sh/ dash解决方案。
查尔斯·罗伯托·卡纳托'17

我建议在该#!行中使用绝对路径,因为该行中的相对路径显然是相对于执行脚本的进程的当前目录而不是相对于脚本所在的位置。
kasperd

Answers:


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.

要查看此手册页,我应该输入man什么?
duleshi 2014年

这是Bash手册页,因此“ man bash”应该这样做。
Insyte 2014年

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

1
+1为posix答案。在一些基本的时序测试中,该case方法似乎是相当老的32位x86计算机上三种方法中最快的。所有这三种都不是一个简单的例子更有效,其管道等叉形标准输入处理器:echo $var | cut -c1。我的分析是非常基础的,仅在一台计算机/操作系统上基于10,000,000次迭代-YMMV。我只是用那台速度较慢的计算机来夸大任何差异,并使差异更加明显-至少在该平台上如此。
胡安

顺便说一句,对于那些10,000,000次迭代,此答案中描述的内置方法运行了大约一分钟(在上述慢速框上)。cut调味管道用了5多个小时。
胡安

如果您想找到以“
Justin

5

我知道这可能是个异端,但是对于这种事情,我宁愿使用grep或egrep而不是在shell中进行。(我猜)这要贵一些,但是对我来说,这种解决方案的可读性弥补了这一点。当然,这是个人喜好问题。

所以:

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

它可以有或没有前导空格。如果您还要考虑前导选项卡,请改用egrep -q'^ [\ t] *#'。


考虑一下,也许我只是更喜欢egrep,因为我喜欢正则表达式,但是我认为grep / egrep在更广泛的情况下还是很有用的。
Eduardo Ivanec

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.