Match a string that contains a newline using sed

后端 未结 4 1261
灰色年华
灰色年华 2020-12-11 02:39

I have a string like this one:

    #
    pap

which basically translates to a \\t#\\n\\tpap and I want to replace it with:

4条回答
  •  死守一世寂寞
    2020-12-11 03:30

    A couple of pure bash solutions:

    Concise, but somewhat fragile, using parameter expansion:

    in=$'\t#\n\tpap\n' # input string
    
    echo "${in/$'\t#\n\tpap\n'/$'\t#\n\tpap\n\tpython\n'}"
    
    • Parameter expansion only supports patterns (wildcard expressions) as search strings, which limits the matching abilities:
    • Here the assumption is made that pap is followed by \n, whereas no assumption is made about what precedes \t#, potentially resulting in false positives.
    • If the assumption could be made that \t#\n\tpap is always enclosed in \n, echo "${in/$'\n\t#\n\tpap\n'/$'\n\t#\n\tpap\n\tpython\n'}" would work robustly; otherwise, see below.

    Robust, but verbose, using the =~ operator for regex matching:

    The =~ operator supports extended regular expressions on the right-hand side and thus allows more flexible and robust matching:

    in=$'\t#\n\tpap' # input string 
    
    # Search string and string to append after.
    search=$'\t#\n\tpap'
    append=$'\n\tpython'
    
    out=$in # Initialize output string to input string.
    if [[ $in =~ ^(.*$'\n')?("$search")($'\n'.*)?$ ]]; then # perform regex matching
        out=${out/$search/$search$append} # replace match with match + appendage
    fi
    
    echo "$out"
    

提交回复
热议问题