В функции ниже (f_ez_sed) я хотел бы просто заменить вхождение "NTH_OCCUR" (0 ~ n). Как я мог это сделать? Я проверил МНОГИЕ методы!

f_ez_sed:

f_ez_sed() {
    : 'Facilitate the use of "sed" functionality .

    Args:
        TARGET (str): Value to be replaced by the REPLACE value.
        REPLACE (str): Value that will replace TARGET.
        FILE (str): File in which the replacement will be made.
        NTH_OCCUR (Optional[int]): Perform the operation only on the indicated 
    occurrence.
    '

    TARGET=$1
    REPLACE=$2

    f_ez_sed_ecp "$TARGET" 1
    TARGET=$F_EZ_SED_ECP_R
    f_ez_sed_ecp "$REPLACE" 1
    REPLACE=$F_EZ_SED_ECP_R

    FILE=$3
    NTH_OCCUR=$4

    ((NTH_OCCUR++))
    SED_RPL="'s/$TARGET/$REPLACE/$NTH_OCCURg'"
    eval "sed -i $SED_RPL $FILE"
}

f_ez_sed "Listen 80" "# Listen 80\nListen 8008" "/etc/apache2/listen.conf" 1

f_ez_sed_ecp:

F_EZ_SED_ECP_R=""
f_ez_sed_ecp() {
    : 'Escape strings to the "sed" command.

    Args:
        VAL_TO_ECP (str): Value to be "escaped".
        DONT_ECP_NL (Optional[int]): 1 - Don't escape "\n" (newline); 
    0 - Escape "\n" (newline). Standard 1.
        DONT_ECP_SQ (Optional[int]): 0 - Don't escape "'" (single quote); 
    1 - Escape "'". Standard 0.

    Returns:
        F_EZ_SED_ECP_R (str): Escaped Value.
    '

    VAL_TO_ECP=$1
    DONT_ECP_NL=$2
    if [ -z "$DONT_ECP_NL" ] ; then
        DONT_ECP_NL=1
    fi
    DONT_ECP_SQ=$3
    if [ -z "$DONT_ECP_SQ" ] ; then
        DONT_ECP_SQ=0
    fi
    F_EZ_SED_ECP_R=$VAL_TO_ECP
    if [ ${DONT_ECP_NL} -eq 1 ] ; then
        F_EZ_SED_ECP_R=$(echo "$F_EZ_SED_ECP_R" | sed 's/\\n/C0673CECED2D4A8FBA90C9B92B9508A8/g')
    fi
    F_EZ_SED_ECP_R=$(echo "$F_EZ_SED_ECP_R" | sed 's/[]\/$*.^|[]/\\&/g')
    if [ ${DONT_ECP_SQ} -eq 0 ] ; then
        F_EZ_SED_ECP_R=$(echo "$F_EZ_SED_ECP_R" | sed "s/'/\\\x27/g")
    fi
    if [ ${DONT_ECP_NL} -eq 1 ] ; then
        F_EZ_SED_ECP_R=$(echo "$F_EZ_SED_ECP_R" | sed 's/C0673CECED2D4A8FBA90C9B92B9508A8/\\n/g')
    fi
}

содержимое "listen.conf":

#Listen 12.34.56.78:80
#Listen 80
#Listen 443


Listen 80


<IfDefine SSL>
    <IfDefine !NOSSL>
        <IfModule mod_ssl.c>

            Listen 443

        </IfModule>
    </IfDefine>
</IfDefine>

2 ответа2

0

Обратите внимание, что

  • /g заменит все вхождения
  • по умолчанию заменяется только первый.

я бы сделал

TARGET=$1
REPLACE=$2
FILE=$3
NTH_OCCUR=$4

while [ $NTH_OCCUR -gt 0 ]
do

  sed -i "s/$TARGET/$REPLACE/" $FILE"
  NTH_OCCUR=$((NTH_OCCUR - 1))

done

и позвонил с

f_ez_sed "^Listen 80" "# Listen 80\nListen 8008" "/etc/apache2/listen.conf" 1

Вы должны использовать ^Listen чтобы использовать привязку начала строки.

0

Я не могу найти способ заменить только в определенной позиции, используя "сед"! Откровенно говоря, я не знаю, можно ли сделать это исключительно с помощью "sed"! Но с помощью приведенного ниже кода вы решите проблему. Очевидно, не перформативно.

f_ez_sed() {
    : 'Facilitate the use of "sed" functionality .

    Args:
        TARGET (str): Value to be replaced by the REPLACE value.
        REPLACE (str): Value that will replace TARGET.
        FILE (str): File in which the replacement will be made.
        NTH_OCCUR (Optional[int]): Perform the operation only on the indicated 
    occurrence.
    '

    TARGET=$1
    REPLACE=$2

    f_ez_sed_ecp "$TARGET" 1
    TARGET=$F_EZ_SED_ECP_R
    f_ez_sed_ecp "$REPLACE" 1
    REPLACE=$F_EZ_SED_ECP_R

    FILE=$3
    NTH_OCCUR=$4
    if [ ${NTH_OCCUR} -gt -1 ] ; then
        ((NTH_OCCUR++))
        for (( i=0; i<$(( $NTH_OCCUR - 1 )); i++ )) ; do
            SED_RPL="'0,/$TARGET/s//£§¢¬¨/g'"
            eval "sed -i $SED_RPL $FILE"
        done
        SED_RPL="'0,/$TARGET/s//$REPLACE/g'"
        eval "sed -i $SED_RPL $FILE"
        SED_RPL="'s/£§¢¬¨/$TARGET/g'"
        eval "sed -i $SED_RPL $FILE"
    else
        SED_RPL="'s/$TARGET/$REPLACE/g'"
        eval "sed -i $SED_RPL $FILE"
    fi
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .