我是否可以在其中重复多个AND参数?

时间:2019-04-02 02:08:26

标签: linux shell unix

我正在尝试在shell中grep多个参数。 我下了./script arg1 arg2 .. argN之类的命令 我希望他们采取行动 egrep -i“ arg1” mydata | egrep -i“ arg2” | ... egrep -i“ argN” | awk -f display.awk 为了匹配AND格式的模式。 我的过程中怎么了?

像这样编写代码是否正确?  egrep -i“ arg1” mydata | egrep -i“ arg2” | ... egrep -i“ argN” | awk -f display.awk 以获得AND格式的多个模式?

if [ $# -eq 0 ]
then
    echo "Usage:phone searchfor [...searchfor]"
    echo "(You didn't tell me what you want to search for.)"
    exit 0
else
    for arg in $*
    do
    if [ $arg -eq $1 ]
    then
            egrep -i "arg" mydata |
    else
            egrep -i "arg" |
    fi
    done
    awk -f display.awk     
fi

如果我的数据有 “快乐的阳光兔子”, “困兔子”, 和“阳光明媚”

我想让他们表演。/script快乐的阳光兔子 然后只有 “快乐的阳光兔子” 出来。

如果我尝试了./script兔子,那么 “快乐的阳光兔子” “困兔子” 都出来了。

3 个答案:

答案 0 :(得分:4)

直接的解决方法是将管道字符移动到done之后。

此外,您应该遍历"$@"以保留参数的引号,通常是quote your variables.

if [ $# -eq 0 ]
then
    # print diagnostics to stderr
    echo "Usage: phone searchfor [...searchfor]" >&2
    echo "(You didn't tell me what you want to search for.)" >&2
    exit 0
fi
for arg in "$@"
do
    # Add missing dash before eq
    if [ "$arg " -eq "$1" ]
    then
        # Surely you want "$arg" here, not the static string "arg"?
        grep -E -i "$arg" mydata
    else
        grep -E -i "$arg"
    fi
done |
awk -f display.awk     

总体逻辑似乎仍然有缺陷;如果有两个以上的参数,则将为第一个参数添加标准输入。也许您想添加一个选项,以允许用户指定输入文件名,并用-指定标准输入?然后所有常规参数都将是搜索字符串,如用法消息所提示。

如果确实打算遍历所有参数以产生逻辑AND,请尝试以下操作:

also () {
    local what
    what=$1
    shift
    if [ $# -gt 0 ]; then
        grep -E -i "$what" | also "$@"
    else
        grep -E -i "$what"
    fi
}

also "$@" <mydata | awk -f display.awk

...尽管更好的实现可能是根据参数构建一个简单的Awk或sed脚本:

script='1'
for arg in "$@"; do
    script="$script && tolower(\$0) ~ tolower(\"$arg\")"
done
awk "$script" | awk -f display.awk

但是,如果搜索词组可能包含正则表达式特殊字符,则这种方法会崩溃(当然,grep -E版本也是如此;但是随后您可以轻松地切换到grep -F)。

将两个Awk脚本合并为一个脚本也应该不难,尽管没有看到display.awk,这是推测性的。

答案 1 :(得分:1)

您可以递归解决它:

#! /bin/bash
if (( $# == 0)); then
  exec cat
else
  arg=$1; shift
  egrep "$arg" | "$0" "$@"
fi

如果不带参数调用脚本,则递归结束。在这种情况下,其行为类似于cat。在您的示例中,您可以将awk放在此处。如果使用一个或多个论点调用了脚本,则会使用第一个参数(egrep)调用$1并将其余参数(移位后的$@)传递给自身({{1} }。

示例:

$0

答案 2 :(得分:0)

使用https://gitlab.com/ole.tange/tangetools/tree/master/G中的G来执行此操作(awk部分除外)。

  

简介

     

G [[grep选项]字符串] [[grep选项]字符串] ...

     

说明

     

G是写作的缩写(搜索与表达式匹配的单行):

grep --option string | grep --option2 string2
     

或-g(搜索与表达式匹配的完整文件):

find . -type f | xargs grep -l string1 | xargs grep -l string1