There are dozens of answers out there... If you don't mind using a bash function schema, below is a good answer. The objective below was to allow using sed with practically any parameter as a KEYWORD (F_PS_TARGET) or as a REPLACE (F_PS_REPLACE). We tested it in many scenarios and it seems to be pretty safe. The implementation below supports tabs, line breaks and sigle quotes for both KEYWORD and replace REPLACE.
NOTES: The idea here is to use sed to escape entries for another sed command.
CODE
F_REVERSE_STRING_R="" f_reverse_string() { : 'Do a string reverse. To undo just use a reversed string as STRING_INPUT. Args: STRING_INPUT (str): String input. Returns: F_REVERSE_STRING_R (str): The modified string. ' local STRING_INPUT=$1 F_REVERSE_STRING_R=$(echo "x${STRING_INPUT}x" | tac | rev) F_REVERSE_STRING_R=${F_REVERSE_STRING_R%?} F_REVERSE_STRING_R=${F_REVERSE_STRING_R#?} } # [Ref(s).: https://stackoverflow.com/a/2705678/3223785 ] F_POWER_SED_ECP_R="" f_power_sed_ecp() { : 'Escape strings for the "sed" command. Escaped characters will be processed as is (e.g. /n, /t ...). Args: F_PSE_VAL_TO_ECP (str): Value to be escaped. F_PSE_ECP_TYPE (int): 0 - For the TARGET value; 1 - For the REPLACE value. Returns: F_POWER_SED_ECP_R (str): Escaped value. ' local F_PSE_VAL_TO_ECP=$1 local F_PSE_ECP_TYPE=$2 # NOTE: Operational characters of "sed" will be escaped, as well as single quotes. # By Questor if [ ${F_PSE_ECP_TYPE} -eq 0 ] ; then # NOTE: For the TARGET value. By Questor F_POWER_SED_ECP_R=$(echo "x${F_PSE_VAL_TO_ECP}x" | sed 's/[]\/$*.^[]/\\&/g' | sed "s/'/\\\x27/g" | sed ':a;N;$!ba;s/\n/\\n/g') else # NOTE: For the REPLACE value. By Questor F_POWER_SED_ECP_R=$(echo "x${F_PSE_VAL_TO_ECP}x" | sed 's/[\/&]/\\&/g' | sed "s/'/\\\x27/g" | sed ':a;N;$!ba;s/\n/\\n/g') fi F_POWER_SED_ECP_R=${F_POWER_SED_ECP_R%?} F_POWER_SED_ECP_R=${F_POWER_SED_ECP_R#?} } # [Ref(s).: https://stackoverflow.com/a/24134488/3223785 , # https://stackoverflow.com/a/21740695/3223785 , # https://unix.stackexchange.com/a/655558/61742 , # https://stackoverflow.com/a/11461628/3223785 , # https://stackoverflow.com/a/45151986/3223785 , # https://linuxaria.com/pills/tac-and-rev-to-see-files-in-reverse-order , # https://unix.stackexchange.com/a/631355/61742 ] F_POWER_SED_R="" f_power_sed() { : 'Facilitate the use of the "sed" command. Replaces in files and strings. Args: F_PS_TARGET (str): Value to be replaced by the value of F_PS_REPLACE. F_PS_REPLACE (str): Value that will replace F_PS_TARGET. F_PS_FILE (Optional[str]): File in which the replacement will be made. F_PS_SOURCE (Optional[str]): String to be manipulated in case "F_PS_FILE" was not informed. F_PS_NTH_OCCUR (Optional[int]): [1~n] - Replace the nth match; [n~-1] - Replace the last nth match; 0 - Replace every match; Default 1. Returns: F_POWER_SED_R (str): Return the result if "F_PS_FILE" is not informed. ' local F_PS_TARGET=$1 local F_PS_REPLACE=$2 local F_PS_FILE=$3 local F_PS_SOURCE=$4 local F_PS_NTH_OCCUR=$5 if [ -z "$F_PS_NTH_OCCUR" ] ; then F_PS_NTH_OCCUR=1 fi local F_PS_REVERSE_MODE=0 if [ ${F_PS_NTH_OCCUR} -lt -1 ] ; then F_PS_REVERSE_MODE=1 f_reverse_string "$F_PS_TARGET" F_PS_TARGET="$F_REVERSE_STRING_R" f_reverse_string "$F_PS_REPLACE" F_PS_REPLACE="$F_REVERSE_STRING_R" f_reverse_string "$F_PS_SOURCE" F_PS_SOURCE="$F_REVERSE_STRING_R" F_PS_NTH_OCCUR=$((-F_PS_NTH_OCCUR)) fi f_power_sed_ecp "$F_PS_TARGET" 0 F_PS_TARGET=$F_POWER_SED_ECP_R f_power_sed_ecp "$F_PS_REPLACE" 1 F_PS_REPLACE=$F_POWER_SED_ECP_R local F_PS_SED_RPL="" if [ ${F_PS_NTH_OCCUR} -eq -1 ] ; then # NOTE: We kept this option because it performs better when we only need to replace # the last occurrence. By Questor # [Ref(s).: https://linuxhint.com/use-sed-replace-last-occurrence/ , # https://unix.stackexchange.com/a/713866/61742 ] F_PS_SED_RPL="'s/\(.*\)$F_PS_TARGET/\1$F_PS_REPLACE/'" elif [ ${F_PS_NTH_OCCUR} -gt 0 ] ; then # [Ref(s).: https://unix.stackexchange.com/a/587924/61742 ] F_PS_SED_RPL="'s/$F_PS_TARGET/$F_PS_REPLACE/$F_PS_NTH_OCCUR'" elif [ ${F_PS_NTH_OCCUR} -eq 0 ] ; then F_PS_SED_RPL="'s/$F_PS_TARGET/$F_PS_REPLACE/g'" fi # NOTE: As the "sed" commands below always process literal values for the "F_PS_TARGET" # so we use the "-z" flag in case it has multiple lines. By Quaestor # [Ref(s).: https://unix.stackexchange.com/a/525524/61742 ] if [ -z "$F_PS_FILE" ] ; then F_POWER_SED_R=$(echo "x${F_PS_SOURCE}x" | eval "sed -z $F_PS_SED_RPL") F_POWER_SED_R=${F_POWER_SED_R%?} F_POWER_SED_R=${F_POWER_SED_R#?} if [ ${F_PS_REVERSE_MODE} -eq 1 ] ; then f_reverse_string "$F_POWER_SED_R" F_POWER_SED_R="$F_REVERSE_STRING_R" fi else if [ ${F_PS_REVERSE_MODE} -eq 0 ] ; then eval "sed -i -z $F_PS_SED_RPL \"$F_PS_FILE\"" else tac "$F_PS_FILE" | rev | eval "sed -z $F_PS_SED_RPL" | tac | rev > "$F_PS_FILE" fi fi }
MODEL
f_power_sed "F_PS_TARGET" "F_PS_REPLACE" "" "F_PS_SOURCE" echo "$F_POWER_SED_R"
EXAMPLE
f_power_sed "{ gsub(/,[ ]+|$/,\"\0\"); print }' ./ and eliminate" "[ ]+|$/,\"\0\"" "" "Great answer (+1). If you change your awk to awk '{ gsub(/,[ ]+|$/,\"\0\"); print }' ./ and eliminate that concatenation of the final \", \" then you don't have to go through the gymnastics on eliminating the final record. So: readarray -td '' a < <(awk '{ gsub(/,[ ]+/,\"\0\"); print; }' <<<\"$string\") on Bash that supports readarray. Note your method is Bash 4.4+ I think because of the -d in readar" echo "$F_POWER_SED_R"
IF YOU JUST WANT TO ESCAPE THE PARAMETERS TO THE SED COMMAND
MODEL
# "TARGET" value. f_power_sed_ecp "F_PSE_VAL_TO_ECP" 0 echo "$F_POWER_SED_ECP_R" # "REPLACE" value. f_power_sed_ecp "F_PSE_VAL_TO_ECP" 1 echo "$F_POWER_SED_ECP_R"
IMPORTANT: If the strings for KEYWORD and/or replace REPLACE contain tabs or line breaks you will need to use the "-z" flag in your "sed" command. More details here.
EXAMPLE
f_power_sed_ecp "{ gsub(/,[ ]+|$/,\"\0\"); print }' ./ and eliminate" 0 echo "$F_POWER_SED_ECP_R" f_power_sed_ecp "[ ]+|$/,\"\0\"" 1 echo "$F_POWER_SED_ECP_R"
NOTE: The f_power_sed_ecp and f_power_sed functions above was made available completely free as part of this project ez_i - Create shell script installers easily!.
outputvar="${inputvar//"$txt2replace"/"$txt2replacewith"}".