测试字符串数组中是否存在字符串

测试字符串数组中是否存在字符串

我正在编写一个脚本,它将文件中每行的前 3 个字母(通过使用 cut 来获取它们)与数组中的字符串进行比较。我已经环顾四周,但我找到的解决方案不适用于我的系统。

现在看起来像这样:

weekdays=([Mon]=1 [Tue]=1 [Wed]=1 [Thu]=1 [Fri]=1 [Sat]=1 [Sun]=1)
input="/Foo/Bar.log"

while read -r line
do

cutline="$(echo ${line} | cut -c 1-3"

if [[ ${weekdays["$cutline"]} ]]
then
echo "Match"
else
echo "No Match"
fi

done < ${input}

该线被正确切断,但测试期间的某些内容会返回误报,因为无论前 3 个字母是什么,它都会返回“匹配”。

当我使用 -x 检查脚本时,它向我展示了,而不是它使用的实际测试

[[ -n 1 ]]

当我用表达式测试它时,[ ]它显示了1

它是否检查数组中的每个字符而不仅仅是整个单词,或者是否还有其他问题?

如果没有问题,是否有另一种方法可以将一行的前 3 个字母与数组中的所有字母进行比较,然后再继续下一个字母?

附带说明:我确实正在运行 Bash 4,所以关联数组应该可以工作

答案1

基本错误是您实际上并未声明关联数组:

$ weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)
$ echo ${weekdays[@]}
1
$ echo ${weekdays[0]}
1
$ echo ${weekdays[2]}

$

我不完全确定 bash 如何处理它以及为什么它只需要一个1,但我确信这不是一个关联数组。正如man bash(强调我的)中所解释的:

如果使用语法 name[下标]=value 分配任何变量,则会自动创建索引数组。下标被视为必须计算为数字的算术表达式。要显式声明索引数组,请使用declare -a name(请参阅下面的SHELL BUILTIN命令)。声明 -a name[下标] 也被接受;下标被忽略。

关联数组是使用声明 -A 名称创建的。

因此,请尝试这样做,它将按您的预期工作:

declare -A weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)

也就是说,您的脚本比您需要的要复杂一些。这是使用相同方法的更简单的版本:

#!/bin/bash
declare -A weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)
input="/Foo/Bar.log"

cut -c 1-3 "$input" | while read -r line; do
    if [[ ${weekdays["$line"]} ]]
    then
            echo "Match : $cutline : ${weekdays[$line]}"
    else
            echo "No Match"
    fi
done    

虽然我可能会这样做:

#!/bin/bash
cut -c 1-3 "$1" | while read -r line; do
        case $line in
        "Mon"|"Tue"|"Wed"|"Thu"|"Fri"|"Sat"|"Sun")
                        echo yes;;
                *)
                        echo no;;
        esac
done

然后,使用目标文件名作为参数运行脚本:

script.sh /Foo/Bar.log"

答案2

我会使用一次文本处理工具的调用来处理文本,不是每行输入都有几个工具:

awk -v 'weekday=(Mon|Tue|Wed|Thu|Fri|Sat|Sun)' '
  {print ($0 ~ "^" weekday ? "" : "No ") "Match"}' < "$input"

如果您需要为输入的每一行运行特定的应用程序,则可以使用循环,但如果只是文本处理(例如将行输出到某个文件),则awk可以这样做:

awk -v 'weekday=Mon|Tue|Wed|Thu|Fri|Sat|Sun' '
  (day = substr($0, 1, 3)) ~ weekday {
    print substr($0, 4) > day ".txt"
  } < "$input"

相关内容