sed를 사용하여 파일의 일부 교체

sed를 사용하여 파일의 일부 교체

xorg 파일의 일부를 교체하고 싶습니다. sed를 사용하여 이 작업을 수행할 수 있습니까?

원본 섹션, 즉 "Screen 섹션"과 "EndSection" 사이의 모든 항목을 바꿉니다...

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

...완전히 새로운 내용(여러 줄)으로 대체되었습니다. 예를 들어

Section "Screen"
    SomeSpecs   "somevalue"
    SomeOptions "somevalues"
EndSection

답변1

sed '/Section "Screen"/,/EndSection/s/\(Identifier.*\)Screen0/\1somethingelse/' xorg-file

인라인을 교체하려면 -ised 뒤에 추가해야 합니다.

답변2

수행 할 수 있지만 sed(구현에 따라 다소 쉽게 sed) perl다음을 사용하는 것이 더 적절할 것입니다.

file=xorg.conf
screen_to_replace=Screen0
new_section='    Identifier "somethingelse"
    Device ...
'

perl -0777 -spi -e '
  s{^\h*Section\h+"Screen"\h*\n\K.*?(?=^\h*EndSection\h*$)}{
    my $section = $&;
    if ($section =~ /^\h*Identifier\h+"\Q$screen_to_replace\E"\h*$/m) {
      $new_section;
    } else {
      $section;
    }
  }smeg' -- -screen_to_replace="$screen_to_replace" \
            -new_section="$new_section" \
         -- "$file"

또는 -MEnglish내장된 문서에 대해 의견을 남겨주세요:

file=xorg.conf
screen_to_replace=Screen0
new_section='    Identifier "somethingelse"
    Device ...
'

perl -MEnglish -0777 -spi -e '
  s{
     ^             # beginning of a line
     \h*           # any amount of horizontal spacing
     Section       # literally
     \h+           # at least one horizontal space
     "Screen"      # literally
     \h*        
     \n            # a line delimiter
     \K            # Keep only what follows from what is matched
     .*?           # anything as little as possibly up until
     (?=           # looking ahead for:
       ^           # beginning of a line
       \h*         # any amount of horizontal spacing
       EndSection  # literally
       \h*         # any amount of horizontal spacing
       $           # the end of a line
     )
  }{
    my $section = $MATCH;
    if ($section =~ m{
      ^           # beginning of a line
      \h*         # any amount of horizontal spacing
      Identifier  # literally
      \h+         # at least one horizontal space
      "\Q$screen_to_replace\E" # "the_old_id", \Q...\E for it to
                               # be taken literally even if it contains
                               # regexp operators.
      \h*         # any amount of horizontal spacing
      $           # the end of a line
    }mx)
    {
      $new_section;
    } else {
      $section;
    }
  }sxmeg' -- -screen_to_replace="$screen_to_replace" \
             -new_section="$new_section" \
          -- "$file"

언급했듯이 어떤 이유로 한 줄의 코드가 필요하지만 가독성에 크게 신경 쓰지 않는 것 같습니다.

perl -0777pi -e's{^\h*Section\h+"Screen"\h*\n\K.*?(?=^\h*EndSection\h*$)}{($s=$&)=~/^\h*Identifier\h+"Screen0"\h*$/m?qq(    Identifier "somethingelse"\n    Device ...\n):$s}smeg' xorg.conf

여기에 있는 모든 매개변수는 하드코딩되어 있습니다.

답변3

먼저 방법을 살펴 보겠습니다.sed 행 선택.

# print ('p') lines between line that contain 'Section' and line that contain 'EndSection'
sed -n '/Section/,/EndSection/ p' xorg.conf
# to same + line starts ('^') with these text
sed -n '/^Section/,/^EndSection/ p' xorg.conf
# to same + 'Section' line must contain 'Screen'
sed -n '/^Section.*Screen/,/^EndSection/ p' xorg.conf

"선택 라인"을 정의하십시오

l1='^Section.*Screen'; l2='^EndSection'
# to same as last command (only for test)
sed -n "/$l1/,/$l2/ p" xorg.conf   # be careful, now use " (double quotes)

마지막으로 몇 가지 대체를 수행합니다( sed"언어" 대체 에서 s). 이제부터 우리는 언제나 평화 $l1롭습니다 $l2!

# replace 'Identifier' by 'BLA1'
sed "/$l1/,/$l2/ s/Identifier/BLA1/" xorg.conf
# replace whole line with 'Identifier' by 'BLA2'
sed "/$l1/,/$l2/ s/Identifier.*/BLA2/" xorg.conf
# and finally what do you want
sed "/$l1/,/$l2/ s/Identifier.*/Identifier \"somethingelse\"/" xorg.conf

관련 정보