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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:32:19  来源:igfitidea点击:

Case insensitive comparision in If condition

bashshell

提问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 patternare changed. Still more details on this are documented by manbash`:

${parameter,,}将字符串中的所有字符转换为小写。如果要转换为大写,请使用${parameter^^}. 如果您只想转换某些字符,请使用${parameter,,pattern}pattern更改匹配的那些字符的位置。manbash`还记录了有关此的更多详细信息:

${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 bashversion 4 (released on 2009-Feb-20) or better.

这些案例修改方法需要bash版本 4(2009 年 2 月 20 日发布)或更高版本。

回答by rici

The bashcase-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