자동 이스케이프 문자가 있는 sed

자동 이스케이프 문자가 있는 sed
CommentAppend() {
    # Comment line and append line below commented line 
    local comment="$1"      # search this line and comment it 
    local append="$2"       # Append this line below commented line 
    local InputFile="$3"    

    sed -i "s/${comment}/#${comment}/g ; s/#${comment}/& \n${append}/" $InputFile
}

이 함수는 이스케이프되지 않은 문자에 대해서는 잘 작동하지만 이스케이프 문자를 사용할 수 있는 경우에는 실패합니다.

그럼 이스케이프 문자에 대한 함수를 만들 수 있을까요?

답변1

다음을 수행할 수 있습니다.

CommentAppend() {
    # Comment line and append line below commented line 
    local comment="$1"      # search this line and comment it 
    local append="$2"       # Append this line below commented line 
    local InputFile="$3"    

    perl -pi -e "s/\Q${comment}\E/#${comment}\n${append}/g" "$InputFile"
}

Perl 정규 표현식의 구분 기호는 \Q...\E그 사이의 모든 내용이 정규 표현식이 아닌 리터럴 문자열로 해석되도록 보장합니다(참고자료 참조 perldoc perlre).

"$InputFile"교체는 한 단계로만 수행할 수 있으며 단어 분리를 방지하려면 파일 이름을 따옴표로 묶어야 합니다(예: ). 이는 또는 를 사용하든 sed적용됩니다 perl.

답변2

agrs로 sed를 확인해 봤는데 -E작동하지 않아서 다음 변경 사항을 사용했는데 작동하는 것 같습니다.

CommentAppend() {
        # Comment line and append line below commented line
        local comment="$( echo "$1" | sed 's/\(\/\)/\\\//g' )"  # search this line and comment it
        local append="$( echo "$2" | sed 's/\(\/\)/\\\//g' )"   # Append this line below commented line
        local InputFile="$3"


        sed -i "s/${comment}/#${comment}/g ; s/#${comment}/& \n${append}/" $InputFile
}

시험

root@router:~# bash -x /tmp/test.sh
+ CommentAppend 'connection = sqlite:////var/lib/keystone/keystone.db' 'connection = mysql://keystoneUser:[email protected]/keystone' /tmp/test.conf
++ sed 's/\(\/\)/\\\//g'
++ echo 'connection = sqlite:////var/lib/keystone/keystone.db'
+ local 'comment=connection = sqlite:\/\/\/\/var\/lib\/keystone\/keystone.db'
++ sed 's/\(\/\)/\\\//g'
++ echo 'connection = mysql://keystoneUser:[email protected]/keystone'
+ local 'append=connection = mysql:\/\/keystoneUser:[email protected]\/keystone'
+ local InputFile=/tmp/test.conf
+ sed -i 's/connection = sqlite:\/\/\/\/var\/lib\/keystone\/keystone.db/#connection = sqlite:\/\/\/\/var\/lib\/keystone\/keystone.db/g ; s/#connection = sqlite:\/\/\/\/var\/lib\/keystone\/keystone.db/& \nconnection = mysql:\/\/keystoneUser:[email protected]\/keystone/' /tmp/test.conf

관련 정보