Shell 脚本 Bash,检查字符串是否以单引号开头和结尾
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40317552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shell script Bash, Check if string starts and ends with single quotes
提问by chichi
I need to check if a string starts and ends with a single quote, for example 'My name is Mozart'
我需要检查字符串是否以单引号开头和结尾,例如“我的名字是莫扎特”
What I have is this, which doesn't work
我有的是这个,这不起作用
if [[ $TEXT == '*' ]] ;
This does not work either
这也不起作用
if [[ $TEXT == /'*/' ]] ;
But if I change it to
但是如果我把它改成
if [[ $TEXT == a*a ]] ;
it works for a sentence like 'an amazing apa'. So I Believe it has to do with the single quote sign.
它适用于像“一个惊人的 apa”这样的句子。所以我相信它与单引号有关。
Any ideas on how I can solve it?
关于如何解决它的任何想法?
回答by Cyrus
回答by Sulav Timsina
I am writing the complete bash script so you won't have any confusion:
我正在编写完整的 bash 脚本,所以您不会有任何困惑:
#! /bin/bash
text1="'helo there"
if [[ $text1 =~ ^\'.*\'$ ]]; then
echo "text1 match"
else
echo "text1 not match"
fi
text2="'hello babe'"
if [[ $text2 =~ ^\'.*\'$ ]]; then
echo "text2 match"
else
echo "text2 not match"
fi
Save the above script as
matchCode.sh
将上面的脚本另存为
matchCode.sh
Now run it as:
./matchCode
现在运行它:
./matchCode
output:
输出:
text1 not match
text2 match
Ask if you have any confusion.
问你是否有任何困惑。
回答by mklement0
Cyrus' helpful answersolves your problem as posted.
赛勒斯的有用回答解决了您发布的问题。
However, I suspect you may be confused over quotes that are part of the shell syntaxvs. quotes that are actually part of the string:
但是,我怀疑您可能对作为 shell 语法一部分的引号与实际上是字符串一部分的引号感到困惑:
In a POSIX-like shell such as Bash,
'My name is Mozart'
is a single-quoted string whose content is the literalMy name is Mozart
- withoutthe enclosing'
. That is, the enclosing'
characters are a syntactic elementsthat tell the shell that everything betweenthem is the literal contentsof the string.By contrast, to create a string whose contentis actually enclosed in
'
- i.e., has embedded'
instances, you'd have to use something like:"'My name is Mozart'"
. Now it is the enclosing"
instances that are the syntactic elements that bookend the string content.- Note, however, that using a
"..."
string (double quotes) makes the contents subject to string interpolation(expansion of embedded variable references, arithmetic and command substitutions; none in the case at hand, however), so it's important to know when to use'...'
(literal strings) vs."..."
(interpolated strings). - Embedding
'
instances in'...'
strings is actually not supported at all in POSIX-like shells, but in Bash, Ksh, and Zsh there's another string type that allows you to do that: ANSI C-quoted strings,$'...'
, in which you can embed'
escaped as\'
:$'\'My name is Mozart\''
- Another option is to use string concatenation: In POSIX-like shells, you can place substrings employing different quoting styles (including unquoted tokens) directlynext to one another in order to form a single string:
"'"'My Name is Mozart'"'"
would also give you a string with contents'My Name is Mozart'
.
POSIX-like shells also allow you to escape individual, unquoted characters(meaning: neither part of a single- nor a double-quoted string) with\
; therefore,\''My name is Mozart'\'
yields the same result.
- Note, however, that using a
在类似 POSIX 的 shell 中,例如 Bash,
'My name is Mozart'
是一个单引号字符串,其内容是文字My name is Mozart
——没有封闭的'
. 也就是说,封闭'
字符是一个句法元素,它告诉外壳它们之间的所有内容都是字符串的文字内容。相比之下,创建一个字符串,其内容实际上是封闭的
'
-即已经嵌入的'
情况下,你必须使用这样的:"'My name is Mozart'"
。现在它是包含"
字符串内容的语法元素的封闭实例。- 但是请注意,使用
"..."
字符串(双引号)会使内容受到字符串插值的影响(嵌入变量引用的扩展、算术和命令替换;但是在手头的情况下没有),因此知道何时使用'...'
(文字字符串)与"..."
(内插字符串)。 '
在'...'
类似 POSIX 的 shell 中实际上根本不支持在字符串中嵌入实例,但是在 Bash、Ksh 和 Zsh 中,还有另一种字符串类型允许您这样做:ANSI C 引用的字符串,$'...'
,您可以在其中嵌入'
转义为\'
:$'\'My name is Mozart\''
- 另一种选择是使用字符串连接:在类似 POSIX 的 shell 中,您可以将采用不同引用样式(包括未加引号的标记)的子字符串直接放在一起,以形成单个字符串:
"'"'My Name is Mozart'"'"
也会为您提供一个包含内容的字符串'My Name is Mozart'
。
类似 POSIX 的 shell 还允许您使用 ; 转义单个未加引号的字符(意思是:既不是单引号字符串的一部分,也不是双引号字符串的一部分)\
。因此,\''My name is Mozart'\'
产生相同的结果。
- 但是请注意,使用
The behavior of Bash's ==
operator inside [[ ... ]]
(conditionals)may have added to the confusion:
Bash==
操作符内部[[ ... ]]
(条件)的行为可能增加了混乱:
If the RHS (right-hand side - the operand to the right of operator ==
) is quoted, Bash treats it like a literal; only unquotedstrings (or variable references) are treated as (glob-like) patterns:
如果引用了 RHS(右侧 - operator 右侧的操作数==
),Bash 会将其视为文字;只有未加引号的字符串(或变量引用)被视为(类似全局的)模式:
'*'
matches literal*
, whereas *
(unquoted!) matches any sequence of characters, including none.
'*'
匹配文字*
,而*
(未加引号!)匹配任何字符序列,包括无。
Thus:
因此:
[[ $TEXT == '*' ]]
would only ever match the single, literal character*
.[[ $TEXT == /'*/' ]]
, because it mistakes/
for the escape character - which in reality is\
- would only match literal/*/
(/'*/'
is effectively a concatenation of unquoted/
and single-quoted literal*/
).[[ $TEXT == a*a ]]
, due to using an unquotedRHS, is the only variant that actually performs pattern matching: any string that starts witha
and ends witha
is matched, includingaa
(because unquoted*
represents any sequence of characters).
[[ $TEXT == '*' ]]
只会匹配单个文字字符*
。[[ $TEXT == /'*/' ]]
,因为它误/
认为转义字符 - 实际上是\
- 只会匹配文字/*/
(/'*/'
实际上是未引用/
和单引号文字的串联*/
)。[[ $TEXT == a*a ]]
,由于使用了未加引号的RHS,它是实际执行模式匹配的唯一变体:任何以 开头a
和结尾的字符串都a
被匹配,包括aa
(因为未加引号*
表示任何字符序列)。
To verify that Cyrus' commands do work with strings whose contentis enclosed in (embedded) single quotes, try these commands, which - on Bash, Ksh, and Zsh - should both output yes
.
要验证 Cyrus 的命令是否适用于内容包含在(嵌入的)单引号中的字符串,请尝试这些命令,它们在 Bash、Ksh 和 Zsh 上都应该输出yes
.
[[ "'ab'" == \'*\' ]] && echo yes # pattern matching, indiv. escaped ' chars.
[[ "'ab'" =~ ^\'.*\'$ ]] && echo yes # regex operator =~