bash If条件中不区分大小写的比较
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26320553/
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
Case insensitive comparision in If condition
提问by Sparshith Puttaswamy Gowda
I have this csv file and i need to count the number of rows which satisfies the condition that the row entry is betwen a certain year range and the artist_name matches the name argument. But the string matching should be case insensitive. How do i achieve that in the if loop..
我有这个 csv 文件,我需要计算满足条件的行数,即行条目介于某个年份范围和艺术家名称与名称参数匹配。但是字符串匹配应该不区分大小写。我如何在 if 循环中实现这一点..
I am a beginner, so please bear with me
我是初学者,所以请多多包涵
#!/bin/bash
file=""
artist=""
from_year="$((-1))"
to_year="$((+1))"
count=0
while IFS="," read arr1 arr2 arr3 arr4 arr5 arr6 arr7 arr8 arr9 arr10 arr11 ; do
if [[ $arr11 -gt $from_year ]] && [[ $arr11 -lt $to_year ]] && [[ $arr7 =~ $artist ]]; then
count=$((count+1))
fi
done < "$file"
echo $count
The $arr7 =~ $artist part is where i need to make the modification
$arr7 =~ $artist 部分是我需要修改的地方
回答by John1024
Bash has a builtin method for converting strings to lower case. Once they are both lower case, you can compare them for equality. For example:
Bash 有一个将字符串转换为小写的内置方法。一旦它们都是小写,您就可以比较它们是否相等。例如:
$ arr7="Rolling Stones"
$ artist="rolling stoneS"
$ [ "${arr7,,}" = "${artist,,}" ] && echo "Matches!"
Matches!
$ [[ ${arr7,,} =~ ${artist,,} ]] && echo "Matches!"
Matches!
Details
细节
${parameter,,}
converts all characters in a string to lower case. If you wanted to convert to upper case, use ${parameter^^}
. If you want to convert just some of the characters, use ${parameter,,pattern}
where only those characters matching pattern
are changed. Still more details on this are documented by man
bash`:
${parameter,,}
将字符串中的所有字符转换为小写。如果要转换为大写,请使用${parameter^^}
. 如果您只想转换某些字符,请使用${parameter,,pattern}
仅pattern
更改匹配的那些字符的位置。man
bash`还记录了有关此的更多详细信息:
${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}Case modification.This expansion modifies the case of alphabetic characters in parameter. The pattern is expanded to produce a pattern just as in pathname expansion. The ^ operator converts lowercase letters matching pattern to uppercase; the , operator converts matching uppercase letters to lowercase. The ^^ and ,, expansions convert each matched character in the expanded value; the ^ and , expansions match and convert only the first character in the expanded value. If pattern is omitted, it is treated like a ?, which matches every character. If parameter is @ or *, the case modification operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the case modification operation is applied to each member of the array in turn, and the expansion is the resultant list.
${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}案例修改。此扩展修改了参数中字母字符的大小写。模式被扩展以产生一个模式,就像在路径名扩展中一样。^ 运算符将匹配模式的小写字母转换为大写;, 运算符将匹配的大写字母转换为小写字母。^^ 和 ,, 扩展转换扩展值中的每个匹配字符;^ 和 , 扩展匹配并仅转换扩展值中的第一个字符。如果省略了模式,则将其视为 ?,匹配每个字符。如果参数为@或*,则对每个位置参数依次进行大小写修改操作,展开即为结果列表。如果参数是一个带有@或*下标的数组变量,
Compatibility
兼容性
These case modification methods require bash
version 4 (released on 2009-Feb-20) or better.
这些案例修改方法需要bash
版本 4(2009 年 2 月 20 日发布)或更高版本。
回答by rici
The bash
case-transformations (${var,,}
and ${var^^}
) were introduced (some time ago) in bash version 4. However, if you are using Mac OS X, you most likely have bash v3.2 which doesn't implement case-transformation natively.
的bash
情况下,转换(${var,,}
和${var^^}
)进行了介绍(前一段时间)在bash版本4.但是,如果您使用的是Mac OS X,你最有可能在没有实现的情况下,改造本身的bash V3.2。
In that case, you can do lower-cased comparison less efficiently and with a lot more typing using tr
:
在这种情况下,您可以效率较低地进行小写比较,并使用以下命令进行更多输入tr
:
if [[ $(tr "[:upper:]" "[:lower:]" <<<"$arr7") = $(tr "[:upper:]" "[:lower:]" <<<"$artist") ]]; then
# ...
fi
By the way, =~
does a regular expression comparison, not a string comparison. You almost certainly wanted =
. Also, instead of [[ $x -lt $y ]]
you can use an arithmetic compound command: (( x < y ))
. (In arithmetic expansions, it is not necessary to use $
to indicate variables.)
顺便说一下,=~
做正则表达式比较,而不是字符串比较。你几乎肯定想要=
。此外,[[ $x -lt $y ]]
您可以使用算术复合命令代替:(( x < y ))
. (在算术展开式中,不必使用$
来表示变量。)
回答by PM 2Ring
Use shopt -s nocasematch
用 shopt -s nocasematch
demo
演示
#!/bin/bash
words=(Cat dog mouse cattle scatter)
#Print words from list that match pat
print_matches()
{
pat=
echo "Pattern to match is '$pat'"
for w in "${words[@]}"
do
[[ $w =~ $pat ]] && echo "$w"
done
echo
}
echo -e "Wordlist: (${words[@]})\n"
echo "Normal matching"
print_matches 'cat'
print_matches 'Cat'
echo -e "-------------------\n"
echo "Case-insensitive matching"
shopt -s nocasematch
print_matches 'cat'
print_matches 'CAT'
echo -e "-------------------\n"
echo "Back to normal matching"
shopt -u nocasematch
print_matches 'cat'
output
输出
Wordlist: (Cat dog mouse cattle scatter)
Normal matching
Pattern to match is 'cat'
cattle
scatter
Pattern to match is 'Cat'
Cat
-------------------
Case-insensitive matching
Pattern to match is 'cat'
Cat
cattle
scatter
Pattern to match is 'CAT'
Cat
cattle
scatter
-------------------
Back to normal matching
Pattern to match is 'cat'
cattle
scatter