我可以在if else中使用多个AND参数吗?

问题描述 投票:1回答:3

我试图在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 bunny那么'快乐的阳光兔子''昏昏欲睡的兔子'都会出来。

linux shell unix
3个回答
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     

整体逻辑似乎仍然存在缺陷;如果有两个以上的参数,你将为第一个参数的grepping标准输入。也许您想添加一个选项以允许用户指定输入文件名,使用-指定标准输入?然后所有常规参数都将是搜索字符串,就像使用消息所暗示的那样。

如果确实意图是遍历所有参数以生成逻辑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
投票

你可以递归地解决它:

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

如果在没有参数的情况下调用脚本,则递归结束。在这种情况下,它的行为就像cat。在你的例子中,你可以把你的awk放在那里。如果使用一个或多个arguemnts调用脚本,则使用第一个参数(egrep)调用$1并将剩余的参数(移位后的$@)传递给自身($0)。

例:

$ ./recursive-egrep sys  < /etc/passwd
sys:x:3:3:sys:/dev:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
$ ./recursive-egrep sys no  < /etc/passwd
sys:x:3:3:sys:/dev:/usr/sbin/nologin

0
投票

使用来自Ghttps://gitlab.com/ole.tange/tangetools/tree/master/G这样做(除了awk部分)。

概要

G [[grep options] string] [[grep options] string] ...

描述

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

grep --option string | grep --option2 string2

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

find . -type f | xargs grep -l string1 | xargs grep -l string1
© www.soinside.com 2019 - 2024. All rights reserved.