sed가 문자열을 대체할 때만 명령을 실행하는 방법

sed가 문자열을 대체할 때만 명령을 실행하는 방법

명령줄을 통해 Ubuntu에서 다중 버스 저장소를 활성화하고 싶습니다.

sed -i "/^# deb.*multiverse/ s/^# //" /etc/apt/sources.list && apt-get update

명령은 매번 실행되지만 행이 주석 처리된 경우 apt-get update에만 필요합니다 .sed

sed문자열이 바뀌었는지 감지하고 해당 결과에 따라 명령을 실행하는 쉬운 방법이 있습니까 ?

답변1

이 질문에 이미 답변이 있다는 것을 알고 있지만 (grep을 허용된 답변으로 사용하지 않고) sed 전용 답변을 제시하는 것이 가능한지 궁금합니다. 결과적으로 이것이 가능해 보입니다:

sed -ni '/^# deb.*multiverse/{;h;s/^# //;};p;${;g;/^#/!q1;}' /etc/apt/sources.list
  && apt-get update

(물론 모든 것이 같은 줄에 있어야 하지만 가로로 스크롤하지 않고도 모든 것이 보이도록 하고 싶습니다.)

설명하다:

  • 패턴 찾기( /^# deb.*multiverse/)
  • 발견된 경우:
    • 예비 버퍼에 라인 유지( h)
    • 주석 해제( s/^# //)
  • 이 줄을 인쇄하세요
  • $마지막 줄( ) 에만
    • 홀딩 버퍼에 있는 라인을 패턴 버퍼에 복사합니다. ( g)
    • 보유 버퍼가 주석 기호로 시작하는지(또는 대체가 발생하지 않은 경우 비어 있는지) 테스트합니다. ( /^#/)
    • 일치하는 항목이 없으면 1대체가 이루어지지 않았음을 나타내는 코드( !q1)로 종료합니다. 그렇지 않으면 코드로 정상적으로 종료합니다 0.

이제 나는 이 대답이 단순히 grep을 사용하는 것만큼 명확하지 않다는 것을 알고 있지만, 나는 이 도전에 관심이 있었고 이것을 요청했기 때문에 공유해야겠다고 생각했습니다.

답변2

아마도 여기서 가장 쉬운 방법은 grep주석 줄을 먼저 추가하는 것입니다.

grep -q '^# deb.*multiverse' /etc/apt/sources.list &&
  sed -i '/^# deb.*multiverse/ s/^# //' /etc/apt/sources.list &&
  apt-get update

답변3

{   sed -i '/^# \(deb.*multiv.*\)/h;s//\1/p
        $x;s//apt-get update/w /dev/fd/2' file
}   2>&1 >/dev/null | sh -v

명령이 읽는 동안 하나 이상의 대체를 수행하면 apt-get update파이프를 통해 공급되는 행만 출력됩니다.shfile

답변4

또 다른 방법은 ed내장 기능을 활용하는 것입니다.표준 입력이 일반 파일인 경우 주소가 지정된 행에 대체가 없으면 오류로 간주됩니다. ed 0이 아닌 종료 상태로 종료되어야 합니다..
당신이 사용할 수있는여기에 문자열:

ed -s /etc/apt/sources.list <<< $',s/^# \\(deb.*multiverse\\)/\\1/\nw\n!apt-get update\nq'

또는트레독:

ed -s /etc/apt/sources.list <<IN
,s/^# \(deb.*multiverse\)/\1/
w
!apt-get update
q
IN

다음 명령을 전달하십시오 ed.

,s/^# \(deb.*multiverse\)/\1/      replace pattern with something 
w                                  write changes to file
!apt-get update                    run this command in shell
q                                  quit editor

그러나 일치하는 항목이 없으면 s대체가 이루어지지 않았으므로 폭격을 당하므로(유일한 ​​출력은 1 을 의미하는 ed물음표임 ) 후속 행의 하위 명령이 실행되지 않습니다. 이를 테스트하기 위해 실제로 또는 같은 다른 명령으로 바꿀 수 있습니다 .?errorapt-get updatecat /etc/apt/sources.listecho DONE


1: 물음표가 귀찮다면 다음 stderr으로 리디렉션하세요 /dev/null.

ed -s /etc/apt/sources.list 2>/dev/null <<....

관련 정보