String 捕获群上的Sed替换

String 捕获群上的Sed替换,string,bash,sed,String,Bash,Sed,我想创建一个bash函数,其行为如下: 如果传递的字符串没有标志,请将第二个参数添加为标志 如果传递了第二个参数中的任何标志,请将其保留在标志中 如果传递任何带有字母c或d的标志,我们将其删除 如果标志中有任何其他字符,我们希望保留这些字符并将第二个参数附加为标志 例如: my_func'cmd模式'ab'#=>cmd-ab模式 my_func'cmd-a模式'ab'#=>cmd-ab模式 my_func'cmd-ac模式'ab'#=>cmd-ab模式 my#func'cmd-aef模式'a

我想创建一个bash函数,其行为如下:

  • 如果传递的字符串没有标志,请将第二个参数添加为标志
  • 如果传递了第二个参数中的任何标志,请将其保留在标志中
  • 如果传递任何带有字母
    c
    d
    的标志,我们将其删除
  • 如果标志中有任何其他字符,我们希望保留这些字符并将第二个参数附加为标志
例如:

my_func'cmd模式'ab'#=>cmd-ab模式
my_func'cmd-a模式'ab'#=>cmd-ab模式
my_func'cmd-ac模式'ab'#=>cmd-ab模式
my#func'cmd-aef模式'ab'#=>cmd-efab模式
my_func'cmd-dead模式'ab'35;=>cmd-efab模式
这就是我尝试过的:

函数my_func(){
回声1美元|
#没有旗帜的箱子
sed“^cmd[^-]/s/^cmd\(.*$\)/cmd-$2\1/”|
#旗帜为2美元或'a'或'b'的箱子`
sed“^cmd-[$2ab]+/s/^cmd-[$2ab]\(.*$\)/cmd-$2\1/”|
#有其他标志的情况
塞德。。。
}
我正在努力解决最后一个问题。我不确定这是否可能,但我很想知道是否可能

它会以某种方式捕获标志(
cmd-\([a-z]\)

然后从捕获组中删除
abcd
sed的/[abcd]//g'
,在组中)

然后取该值并在输出中附加
ab


如果知道是否有一个更好的实现使用的不是
sed

的话也会很酷,正如评论中提到的,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
}

你知道<代码>案例吗。。。。。esacshell中的语法?我认为这样做可以更容易地完成您想要的任务,并且可以减少/不需要外部进程调用(即
sed
)。我认为
-[$2ab]+
不会按照您需要的方式工作,或者您是否对其进行了彻底的测试?祝你好运。我也会考虑使用<代码> GETopts 可能对你有帮助。
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;
        }
    '
}