在bash中将命令的输出匹配到数组

时间:2014-01-09 22:57:05

标签: arrays linux bash

我一直在搜索,但找不到这个问题的答案。我想将特定命令的输出与我脚本中的数组相匹配。我是一个perl编码器但我必须使用的系统类型的限制我不能使用perl而且我必须求助于bash我的脚本。它是Debian 5.0.6作为FYI。

因此,每当我的sudo命令在特定的IP上运行时,它就会提供我的数组中的某些单词。我需要将数组中的任何单词与输出中的任何单词进行匹配。

此阵列也需要查看228种不同的内容。

我的电子邮件变量是在找到它时发送,并且单独工作正常。

array=("City1" "City2" "City 3")

sudo -u user /usr/local/bin/someprogram.pl x.x.x.x;
MATCH1=`grep "$array"`
if [ "{$MATCH1}" != ""]
then
    do $email
else done
fi

我很感激对此有任何帮助。我为我的bash脚本无知而道歉。

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题:您可以遍历返回的每一行,并遍历每个模式,如果匹配则发送电子邮件。

sudo -u user /usr/local/bin/someprogram.pl x.x.x.x | while read line; do
    for pattern in "${array[@]}"; do
        if [[ $line =~ $pattern ]]; then
            $email
            break  # exit after the first match, or comment out if you want to keep going
        fi
    done
done

<强>更新

如果你有很多模式和很多行,那么脚本可能会很慢。也许你可以在每行打印一个点作为“进度指示器”,例如:

sudo -u user /usr/local/bin/someprogram.pl x.x.x.x | while read line; do
    printf .       # prints a dot without linebreak
    for pattern in "${array[@]}"; do
        if [[ $line =~ $pattern ]]; then
            echo   # just to clear the line after the printf statements
            $email
            break  # exit after the first match, or comment out if you want to keep going
        fi
    done
done
echo   # clear the line after the printf statements

答案 1 :(得分:0)

我认为Janos的解决方案更好,因为它更具可读性和可维护性,但这里的解决方案更像您提供的代码模板:

#!/bin/bash

printWords() {
  echo City 1 City x
  echo City 2
  echo City y
  echo City 3
}

CMD_OUTPUT=$(printWords)

array=("City 1" "City 3")

MATCH=$(echo $CMD_OUTPUT | grep -E "${array[0]}${array[*]/#/|}")

if [ -n "$MATCH" ] ; then
    echo email
fi
在这种情况下,

${array[0]}${array[*]/#/$(echo \|)}会产生City 1|City 1 |City 3。第二个替换${array[*]/#/|}匹配每个数组元素的(空)开头,并将其替换为管道符号|以构造OR正则表达式。然而,正则表达式将以管道符号开头,因此也匹配任何空字符串,这就是我在数组的第一个元素前置的原因。另请注意[@][*]的使用。