我想检查字符串是否以“ node”开头,例如“ node001”。 就像是

if [ $HOST == user* ]  then  echo yes
fi

我该怎么做?


我还需要结合表达式来检查HOST是“ user1”还是以“ node”开头

if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi> > > -bash: [: too many arguments

如何正确做?


#1楼

我一直尝试使用POSIX sh而不是使用bash扩展,因为脚本编写的主要要点之一是可移植性。 (除了连接程序,不要替换它们)

在sh中,有一种简单的方法可以检查“ is-prefix”条件。

case $HOST in node*)your code here
esac

鉴于sh的年代,神秘和脆弱(而且bash不能治愈:它更加复杂,一致性较差且不便于移植),我想指出一个非常不错的功能方面:尽管构建了诸如case一些语法元素,在结果上,构造与其他工作没有什么不同。 它们可以用相同的方式组成:

if case $HOST in node*) true;; *) false;; esac; thenyour code here
fi

甚至更短

if case $HOST in node*) ;; *) false;; esac; thenyour code here
fi

甚至更短(仅作为语言元素呈现!但是现在这是不好的样式)

if ! case $HOST in node*) false;; esac; thenyour code here
fi

如果您喜欢露骨,请构建自己的语言元素:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }

这实际上不是很好吗?

if beginswith node "$HOST"; thenyour code here
fi

由于sh基本上只是作业和字符串列表(以及内部进程,由作业组成),我们现在甚至可以执行一些轻量级的函数编程:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
checkresult() { if [ $? = 0 ]; then echo TRUE; else echo FALSE; fi; }all() {test=$1; shiftfor i in "$@"; do$test "$i" || returndone
}all "beginswith x" x xy xyz ; checkresult  # prints TRUE
all "beginswith x" x xy abc ; checkresult  # prints FALSE

真优雅 我并不是建议在严重的事情上使用sh -在现实世界中,它会很快崩溃(没有lambda,因此必须使用字符串。但是不能使用字符串嵌套函数调用,也不能使用管道...)


#2楼

由于#在bash中具有含义,因此我得到了以下解决方案。
另外,我更喜欢用“”来包装字符串,以克服空格等问题。

A="#sdfs"
if [[ "$A" == "#"* ]];thenecho "skip comment line"
fi

#3楼

您可以只选择要检查的字符串部分:

if [ "${HOST:0:4}" = user ]

对于后续问题,您可以使用OR :

if [[ "$HOST" == user1 || "$HOST" == node* ]]

#4楼

如果您使用的是最新的bash(v3 +),建议使用bash regex比较运算符=~ ,即

if [[ "$HOST" =~ ^user.* ]]; thenecho "yes"
fi

要匹配this or that正则表达式中的| ,即

if [[ "$HOST" =~ ^user.*|^host1 ]]; thenecho "yes"
fi

注意-这是“正确”的正则表达式语法。

  • user*表示r use和零个或多个出现,因此useuserrrr将匹配。
  • user.*表示user和任何字符的零个或多个出现,因此user1userX将匹配。
  • ^user.*表示在$ HOST开头匹配模式user.*

如果您不熟悉正则表达式语法,请尝试参考此资源 。

注意-如果您将每个新问题作为一个新问题进行询问会更好,这会使stackoverflow更加整洁并且更有用。 您始终可以包含指向上一个问题的链接以供参考。


#5楼

《 高级Bash脚本指南》中的此代码段说:

# The == comparison operator behaves differently within a double-brackets
# test than within single brackets.[[ $a == z* ]]   # True if $a starts with a "z" (wildcard matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

所以你几乎正确了。 您需要括号,而不是单括号。


关于第二个问题,您可以这样写:

HOST=user1
if  [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
thenecho yes1
fiHOST=node001
if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
thenecho yes2
fi

哪个会回声

yes1
yes2

Bash的if语法很难习惯(IMO)。


#6楼

我更喜欢已经发布的其他方法,但是有些人喜欢使用:

case "$HOST" in user1|node*) echo "yes";;*)echo "no";;
esac

编辑:

我已将您的替代品添加到上述案例声明中

在您编辑的版本中,括号太多。 它看起来应该像这样:

if [[ $HOST == user1 || $HOST == node* ]];

#7楼

if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi

无效,因为所有[[[测试]都识别相同的非递归语法。 请参见bash手册页中的“ 条件表达式”部分。

顺便说一句,SUSv3说

在早期的提议中,从KornShell派生的条件命令(双括号[[]] )已从Shell命令语言描述中删除。 有人提出反对,认为真正的问题是滥用测试命令( [ ),将其放入外壳是解决问题的错误方法。 相反,适当的说明文件和一个新的shell保留字( )就足够了。

可以使用单独的test命令和shell逻辑调用在shell级别上完成需要多次测试操作的测试 ,而不是使用test的容易出错的-o标志。

您需要以这种方式编写它,但是测试不支持它:

if [ $HOST == user1 -o $HOST == node* ];
then
echo yes
fi

测试使用=来实现字符串相等,更重要的是它不支持模式匹配。

case / esac对模式匹配有很好的支持:

case $HOST in
user1|node*) echo yes ;;
esac

它具有不依赖bash的附加优点,语法可移植。 从单一Unix规范的Shell命令语言:

case word in[(]pattern1) compound-list;;[[(]pattern[ | pattern] ... ) compound-list;;] ...[[(]pattern[ | pattern] ... ) compound-list]
esac

#8楼

@OP,对于两个问题,您都可以使用case / esac

string="node001"
case "$string" innode*) echo "found";;* ) echo "no node";;
esac

第二个问题

case "$HOST" innode*) echo "ok";;user) echo "ok";;
esaccase "$HOST" innode*|user) echo "ok";;
esac

或Bash 4.0

case "$HOST" inuser) ;& node*) echo "ok";;
esac

#9楼

虽然我在这里找到大多数答案都是正确的,但其中许多包含不必要的批评。 POSIX参数扩展可满足您的所有需求:

[ "${host#user}" != "${host}" ]

[ "${host#node}" != "${host}" ]

${var#expr}${var} expr最小的前缀匹配expr并返回。 因此,如果${host} 不是usernode )开头,则${host#user}${host#node} )与${host}相同。

expr允许使用fnmatch()通配符,因此${host#node??}和朋友也可以使用。


#10楼

你可以做的另一件事是cat出你是什么呼应和管道与inline cut -c 1-1


#11楼

在Mark Rushakoff的最高排名答案中添加了更多语法细节。

表达方式

$HOST == node*

也可以写成

$HOST == "node"*

效果是一样的。 只要确保通配符在引号之外即可。 如果通配符引号内,则将按字面意义进行解释(即不作为通配符)。


#12楼

我调整了@markrushakoff的答案,使其成为可调用的函数:

function yesNo {# prompts user with $1, returns true if response starts with y or Y or is empty stringread -e -p "
$1 [Y/n] " YN[[ "$YN" == y* || "$YN" == Y* || "$YN" == "" ]]
}

像这样使用它:

$ if yesNo "asfd"; then echo "true"; else echo "false"; fiasfd [Y/n] y
true$ if yesNo "asfd"; then echo "true"; else echo "false"; fiasfd [Y/n] Y
true$ if yesNo "asfd"; then echo "true"; else echo "false"; fiasfd [Y/n] yes
true$ if yesNo "asfd"; then echo "true"; else echo "false"; fiasfd [Y/n]
true$ if yesNo "asfd"; then echo "true"; else echo "false"; fiasfd [Y/n] n
false$ if yesNo "asfd"; then echo "true"; else echo "false"; fiasfd [Y/n] ddddd
false

这是提供指定默认值的更复杂的版本:

function toLowerCase {echo "$1" | tr '[:upper:]' '[:lower:]'
}function yesNo {# $1: user prompt# $2: default value (assumed to be Y if not specified)# Prompts user with $1, using default value of $2, returns true if response starts with y or Y or is empty stringlocal DEFAULT=yesif [ "$2" ]; then local DEFAULT="$( toLowerCase "$2" )"; fiif [[ "$DEFAULT" == y* ]]; thenlocal PROMPT="[Y/n]"elselocal PROMPT="[y/N]"firead -e -p "
$1 $PROMPT " YNYN="$( toLowerCase "$YN" )"{ [ "$YN" == "" ] && [[ "$PROMPT" = *Y* ]]; } || [[ "$YN" = y* ]]
}

像这样使用它:

$ if yesNo "asfd" n; then echo "true"; else echo "false"; fiasfd [y/N]
false$ if yesNo "asfd" n; then echo "true"; else echo "false"; fiasfd [y/N] y
true$ if yesNo "asfd" y; then echo "true"; else echo "false"; fiasfd [Y/n] n
false

#13楼

grep

忘了性能,这是POSIX,看起来比case解决方案好:

mystr="abcd"
if printf '%s' "$mystr" | grep -Eq '^ab'; thenecho matches
fi

说明:

  • printf '%s'防止printf扩展反斜杠转义符 : bash printf文字逐字字符串
  • grep -q防止回显匹配项到标准输出: 如何使用Bash检查文件是否包含特定字符串
  • grep -E启用扩展的正则表达式,这是我们需要的^

在bash中,如何检查字符串是否以某个值开头?相关推荐

  1. java中如何检查字符串都是数字_如何在Java中检查字符串是否为数字?

    我们将检查字符串是否为数字-借助逻辑,我们将解决此问题,第一步,我们将使用一个名为str的字符串变量,并将任何值存储在其中. 在第二步中,我们将使用一个名为str_numeric的布尔变量,该变量存储 ...

  2. 在JAVA中如何检查字符串日期的合法性

    在SWT中还没有日期控件,所以我的日期是用文本框手工输入的,这时就需要验证输入的日期是否合法.在之前我是复制很久以前写的一段代码,它的解决方法是分解日期字串,然后检查,这很笨且不严格.正确的方案应该是 ...

  3. python如何判断列表是否为空_Python中如何检查字符串/列表是否为空

    本文最后更新于2018年5月5日,已超过 1 年没有更新,如果文章内容失效,还请反馈给我,谢谢! =Start= 缘由: 整理.记录.备忘 正文: 参考解答: 从dict中取值时,一定要使用.get( ...

  4. PowerDesigner中如何给字符串字段设置默认值 .

    参考:http://www.cnblogs.com/navy235/archive/2011/10/18/2216443.html 在PowerDesigner12.5中,给varchar或nvarc ...

  5. linux下字符串操作,Linux Bash 中字符串操作

    所谓"子字符串"就是出现在其它字符串内的字符串. 比如 "3382" 就是 "this is a 3382 test" 的子字符串. 我们有 ...

  6. linux bash 字符串 连接,Linux Bash 中字符串操作

    Linux Bash 中字符串操作 所谓 "子字符串" 就是出现在其它字符串内的字符串. 比如 "3382" 就是 "this is a 3382 t ...

  7. bash中分割字符串

    #!/bin/bash IFS=',' read -ra LIST <<< "$nodes" IFS=' ' for node in ${LIST[@]} doe ...

  8. python中return输出字符串_python基础——字符串

    Python 字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 创建字符串很简单,只要为变量分配一个值即可.例如: var1 = 'Hello W ...

  9. 如何在Bash中比较字符串

    如何将变量与字符串进行比较(如果匹配则执行某些操作)? #1楼 要将字符串与通配符进行比较,请使用 if [[ "$stringA" == *$stringB* ]]; then# ...

最新文章

  1. 【ACM】杭电OJ 2044 2045
  2. java易语言_java程序员,0基础学习开发易语言。
  3. Spring Boot 密码加密的 2 种姿势!
  4. 有源晶振和无源晶振的输出波形
  5. 万用表怎么测量电池容量_如何使用万用表,使用万用表测量常用的六个方面
  6. java连接池域名切换_java - 使用JDBC的连接池选项:DBCP与C3P0
  7. 惊喜不止小米9!小米又一4800万新机确认:不给友商机会?
  8. 摆花(2012Noip普及组第3题)
  9. 部署Django工程
  10. 分享一些经典的特效效果,希望对大家有帮助
  11. [Google标准文档]如何做好代码评审
  12. 基于keras实现双向GRU的中文情感分析
  13. 【教3妹学java】JVM调优有哪些工具?
  14. PO 审批 PO Release
  15. C++ 数组array与vector的比较
  16. 【收藏】一些实用的分割线
  17. 刮刮彩票 (20 分)
  18. 软件工程知识点总结——第三、四部分
  19. 搭建Android上的服务器
  20. zip直链生成网站_调优-WEB资讯专栏-DMOZ中文网站分类目录

热门文章

  1. Go 语言本身提供的包管理机制
  2. atitit.激活一个窗口总结 swing java .net php
  3. 数据结构——动态链表
  4. Discuz X3.1 论坛修改的方法
  5. 如何才能成为一个高效工作的软件工程师?
  6. bzoj 3232: 圈地游戏【分数规划+最小割】
  7. jQuery 开始动画,停止动画
  8. 本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github
  9. 【有意思的BUG】需要停止的进程
  10. android的ant脚本build.xml自动生成模板