Замена седа на группе захвата - PullRequest
1 голос
/ 29 мая 2019

Я хотел бы создать функцию bash, которая ведет себя следующим образом:

  • Если передана строка без флагов, добавьте второй аргумент в качестве флагов
  • Если передан любойфлаг, который находится во втором аргументе, оставьте его в флажках.
  • Если передан любой флаг с буквой c или d, мы удалим его.
  • Если есть какой-либо другойсимвол в флаге, мы хотим сохранить их и добавить второй аргумент в качестве флагов.

Например:

my_func 'cmd pattern' 'ab' #=> cmd -ab pattern
my_func 'cmd -a pattern' 'ab' #=> cmd -ab pattern
my_func 'cmd -ac pattern' 'ab' #=> cmd -ab pattern
my_func 'cmd -aef pattern' 'ab' #=> cmd -efab pattern
my_func 'cmd -deaf pattern' 'ab' #=> cmd -efab pattern

Это то, что я пробовал:

function my_func() {
  echo $1 |
  # case with no flags
  sed "/^cmd [^-]/s/^cmd \(.*$\)/cmd -$2 \1/" |
  # case with flags in $2 or `a` or `b`
  sed "/^cmd -[$2ab]+ /s/^cmd -[$2ab] \(.*$\)/cmd -$2 \1/" |
  # case with other flags
  sed ...
}

Я борюсь с последним.Я не уверен, если это возможно, но хотел бы знать, если это так.

Это как-то захватывает флаги (cmd -\([a-z]\)),

, затем удаляет abcd из захватаgroup (sed 's/[abcd]//g' в группе)

, затем принять это значение и добавить ab в вывод.

Было бы также здорово узнать, есть ли более хорошая реализация, использующая что-то другоечем sed

1 Ответ

1 голос
/ 29 мая 2019

Как уже упоминалось в комментариях, sed, вероятно, не нужен.

Вот чистая версия bash:

my_func(){
    local cmd arg1 rest flags

    if [[ $2 =~ [^a-zA-Z0-9] ]]; then
        echo 1>&2 "bad character in arg2"
        exit 1
    fi

    read -r cmd arg1 rest <<< $1

    if [[ $arg1 =~ ^[^-] ]]; then
        # no flags
        echo "$cmd -$2 $arg1${rest:+ $rest}"
    else
        # have flags

        # strip unwanted/duplicates and append new
        eval 'flags=${arg1//[cd'$2']/}$2'

        # append new flags and return
        echo "$cmd $flags $rest"
    fi
}

eval опасно, если переданы недоверенные данные (как и ваши sed, использующие $2 без проверки) - всегда проверяйте работоспособность - я предположил, что флаги должны быть буквенно-цифровыми.


Если вы хотите использовать sed, это должно сработать (то же самое с предупреждением о проверке работоспособности $2:

my_func(){
    sed <<< $1 '
        /^\([^ ][^ ]*\) \([^-]\)/ { # no flags
            s//\1 -'$2' \2/;
            q;
         }
        /^[^ ][^ ]* -\([^ ]*\) .*/ { # has flags
            h;
            s//\1/;
            s/[cd'$2']//g;
            G;
            s/^\([^\n]*\)\n\([^ ][^ ]* -\)[^ ]*\( .*\)/\2\1'$2'\3/;
            q;
        }
        {
            s/.*/#ERROR: malformed input/;
            q;
        }
    '
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...