Динамическое построение командной трубы в Bash - PullRequest
0 голосов
/ 27 сентября 2018

Я пишу программу bash, которая принимает параметры.

Например: ./my_program -l 3 -a -s

  • -l 3 ограничит вывод тремя строками
  • -a выберет весь мой файл
  • -s отсортирует вывод

На данный момент я мог бы использовать два варианта одновременно таким образом:

if [ $all == 1 ]
then
    if [ $sort == 1 ]
    then
        printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | sort
    else
        printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//'
    fi
fi

Если опция -a, я печатаю весь файл, или, если опция -a и опция -s, я использую ту же команду, но я использую sort.

С этим решением,если я захочу реализовать -l, это создаст много операторов if.

Сначала я подумал о создании переменной, содержащей мою команду.

Пример:

sort='sort'
limit='grep -m3'

и затем напишите мою команду следующим образом:

printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | $sort | $limit

Но это просто не работает.

Дело в том, что я хотел бы написать основную команду и бытьвозможность добавить к этому больше, в зависимости от опций.

Как я могу сделать это правильно без тонны операторов "if"?

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

Вы можете напрямую передать оператор if.Для этого потребуется фильтр без операции, такой как cat, хотя в некоторых местах он несколько менее эффективен в этом отношении.

printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' |
 if [ "$sort" = 1 ]; then sort; else cat; fi |
 if [ "$l" -gt 0 ]; then grep -m"$l"; else cat; fi

Оператор if сам по себе является командой, поэтому онимеет свои собственные наборы файловых дескрипторов, которые наследуют вложенные команды.Сам оператор if ничего не делает с этими дескрипторами, поэтому sort и cat оба видят данные, которые были бы, если бы они не были обернуты в первую очередь.

0 голосов
/ 16 октября 2018

Хорошо, все.Я отвечаю немного поздно.Я не знал, что смогу использовать кошку в качестве запрета, и именно это решение я искал.Таким образом, я просто инициализировал все свои варианты с помощью "cat" op.Если опция срабатывает правильно, я просто обновляю строку с хорошей операцией.Затем мне просто нужно было написать одну строку со всеми опциями.

Большое спасибо.

0 голосов
/ 27 сентября 2018

Отличный вопрос с хитрым, не столь очевидным решением.

То, что вы можете сделать, это соединить пару вызовов функций.Эти функции могут проверять соответствующие флаги, а затем либо «делать что-то», например, вызывать sort, либо «ничего не делать», и просто вызывать cat.Простой cat вызов в конвейере, по сути, не предназначен: он копирует стандартный ввод в стандартный вывод без изменений.

maybe_sort() {
    if [[ $sort == 1 ]]; then
        sort
    else
        cat
    fi
}

maybe_limit() {
    if [[ -n $limit ]]; then
        head -n "$limit"
    else
        cat
    fi
}

Чтобы использовать их, вы должны написать:

printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | maybe_sort | maybe_limit
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...