Могу ли я найти несколько аргументов AND в if else? - PullRequest
1 голос
/ 02 апреля 2019

Я пытаюсь получить несколько аргументов в оболочке. Я помещаю заказы как ./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 happy солнечный зайчик только тогда 'счастливый солнечный зайчик' выходит.

и если бы я попробовал ./script bunny, то 'счастливый солнечный зайчик' "сонный зайчик" оба выходят.

Ответы [ 3 ]

4 голосов
/ 02 апреля 2019

Немедленное исправление заключается в перемещении символа канала после done.

. Кроме того, вы должны перебрать "$@", чтобы сохранить в кавычках ваши аргументы, и, как правило, заключите в кавычки ваши переменные..

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     

Общая логика все еще кажется ошибочной;вы будете использовать стандартный ввод для первого аргумента, если есть более двух аргументов.Возможно, вы хотите добавить опцию, позволяющую пользователю указать имя входного файла, с - для указания стандартного ввода?И тогда все обычные аргументы будут строками поиска, как подсказывает сообщение об использовании.

Если на самом деле намерение состоит в том, чтобы перебрать все аргументы для создания логического И, попробуйте следующее:

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 голос
/ 02 апреля 2019

Вы можете решить это рекурсивно:

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

Рекурсия заканчивается, если скрипт вызывается без аргументов. В этом случае он ведет себя как cat. В вашем примере вы можете поместить туда awk. Если скрипт вызывается с одним или несколькими аргументами, он вызывает 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 голосов
/ 26 апреля 2019

Используйте G из https://gitlab.com/ole.tange/tangetools/tree/master/G, что делает это (за исключением части awk).

СИНОПСИС

G [[параметры grep]]] [[grep options] string] ...

ОПИСАНИЕ

G - это сокращение от записи (поиск одинарных строк, соответствующих выражениям):

grep --option string | grep --option2 string2

или с-g (поиск полных файлов, соответствующих выражениям):

find . -type f | xargs grep -l string1 | xargs grep -l string1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...