sed를 사용하여 특수 문자가 포함된 문자열을 특수 문자가 포함된 다른 문자열로 대체

sed를 사용하여 특수 문자가 포함된 문자열을 특수 문자가 포함된 다른 문자열로 대체

bash 프롬프트를 .bashrc의 다른 프롬프트로 자동 전환하려고 합니다.

원래 문자열:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

교체 문자열:

IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
PS1='\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] '

이를 위해 bash를 작성하려는 많은 잘못된 시도 중 하나는 다음과 같습니다.

#!/bin/bash
original="PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '"
replacement="PS1='\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] '" 
ipvar="IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print \$2}' | cut -c 6- )"

cp ~/.bashrc ~/.bashrc.bak
sed -e 's/$original/$replacement/g' ~/.bashrc

sed에서 '\', '/' 및 '&'를 이스케이프해야 한다는 것을 알고 있기 때문에 모든 문자를 이중 이스케이프 처리해 보았습니다. 나는 이 문제를 이해할 수 없는 것 같다.

첫 번째 회선을 교체할 수 없었기 때문에 IP 회선을 바로 연결하려고 애쓰지도 않았습니다.

이러한 유형의 자동화를 위한 더 좋은 방법이 있다면 알려주시기 바랍니다.

답변1

다음은 몇 가지 방법입니다(2.5).

  • PS1공통 템플릿을 따르도록 설정을 단계별로 수정하는 데 관심이 있다면 ,

    • 해당 행만 포함하는 파일을 만듭니다 PS1=….
    • sed예를 들어 섹션별로 편집하는 명령을 작성합니다 .
      • sed -e 's/${debian_chroot:+($debian_chroot)}/\\d \\t /'
      • sed -e 's/\\033/\\e/g'
      • 등.
    • 더 작고 간단한 명령을 디버그하는 것이 더 쉬울 수도 있습니다. 모든 작업이 완료되면 모든 작업을 하나로 연결하는 것이 간단해집니다.
    • 보고 있다의 가치 $original? 예를 들어, 끝났나요
              printf "%s\n" "$original"
      ? 당신이 다음과 같은 말을 할 때 이것만 기억하세요.

      "The quick brown fox 'jumps over' the lazy dog."
      

      전체 문자열은 다음 위치에 있습니다.더블인용 부호. 그래서 당신이 말할 때

      "Humpty '$var' Dumpty"
      

      $var큰따옴표로 묶여 있기 때문에 확장 됩니다 .

      이제 문자열을 살펴보십시오 original.

      original="PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:…"
      

      ${debian_chroot:+($debian_chroot)}그렇게 할당하면 범위가 확장됩니다. 그래서 이것은 문제입니다.

  • 이미 존재하는 값으로 새 값을 변경하려면 PS1여우 조각상을 깎은 다음 개 조각상을 만들기 위해 점토를 추가하지 말고 sed'' 를 사용하여 기존 할당을 삭제하고 교체하세요. 초 c(hange) 명령은 하나 이상의 라인 세트를 하나 이상의 라인 세트로 대체합니다.

    sed -e $'/^PS1=/c\
    IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk \'{print $2}\' | cut -c 6- )\
    PS1=\'\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] \''
    

    원시 문자를 문자열에 넣을 수 있도록 sed전체 명령 문자열을 여기에 넣었습니다 . 원한다면 검증된 방법을 사용할 수 있습니다.$'…'\''

    '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'
    

    (대체 참조) 기술.

  • 위의 변형은

    sed -e $'/^PS1=/{s/^/# /; a\
    IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk \'{print $2}\' | cut -c 6- )\
    PS1=\'\d \t \[\e[0;31m\]\u@$IPeth0\[\e[0;32m\]:\[\e[0;36m\]\w# \[\e[m\] \'
    }'
    

    기존 정의( s/^/# /) 를 주석 처리하고새 줄을 추가하려면 이 명령을 사용하십시오 a.

관련 정보