code

sed를 사용하여 일치하는 두 패턴 사이의 모든 줄 삭제

codestyles 2021. 1. 7. 07:59
반응형

sed를 사용하여 일치하는 두 패턴 사이의 모든 줄 삭제


다음과 같은 파일이 있습니다.

# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah

sed 명령을 사용하여 #$사이의 모든 행을 삭제하려면 어떻게해야합니까? 따라서 결과는 다음과 같습니다.

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

친절하게 설명해 주시겠습니까?


이를 위해 다음 sed 명령을 사용하십시오.

sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt

extra characters at the end of d command오류 방지를 위해 Mac 사용자 는 닫는 대괄호 앞에 세미콜론을 추가해야합니다.

sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt

산출

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

설명:

  • /^#/,/^\$/로 시작하는 줄 사이의 모든 텍스트 #$. ^줄 문자의 시작에 사용됩니다. $특수 문자이므로 이스케이프해야합니다.
  • /^#/! 줄의 시작이 아닌 경우 다음을 수행함을 의미합니다. #
  • /^$/! 줄의 시작이 아닌 경우 다음을 수행함을 의미합니다. $
  • d 삭제를 의미합니다

그래서 전반적인 먼저 모든 라인 일치한다 ^#^\$다음 라인을 찾는 것과 일치하는 선에서 일치하지 않는 ^#일치하지 않는 ^\$ 및 사용하여 삭제를 d.


$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3

일반적으로 abcde 형식의 내용이있는 파일이있는 경우 섹션 a 가 패턴 b 앞에 있고 섹션 c 가 패턴 d 앞에 있고 섹션 e 뒤에 있고 다음 sed명령 을 적용하면 다음 과 같은 결과가 나타납니다.

In this demonstration, the output is represented by => abcde, where the letters show which sections would be in the output. Thus, ae shows an output of only sections a and e, ace would be sections a, c, and e, etc.

Note that if b or d appear in the output, those are the patterns appearing (i.e., they're treated as if they're sections in the output).

Also don't confuse the /d/ pattern with the command d. The command is always at the end in these demonstrations. The pattern is always between the //.

  • sed -n -e '/b/,/d/!p' abcde => ae
  • sed -n -e '/b/,/d/p' abcde => bcd
  • sed -n -e '/b/,/d/{//!p}' abcde => c
  • sed -n -e '/b/,/d/{//p}' abcde => bd
  • sed -e '/b/,/d/!d' abcde => bcd
  • sed -e '/b/,/d/d' abcde => ae
  • sed -e '/b/,/d/{//!d}' abcde => abde
  • sed -e '/b/,/d/{//d}' abcde => ace

Another approach with sed:

sed '/^#/,/^\$/{//!d;};' file
  • /^#/,/^\$/: from line starting with # up to next line starting with $
  • //!d: delete all lines except those matching the address patterns

I did something like this long time ago and it was something like:

sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"

Which is something like:

  • -n suppress all output
  • -e "1,/# ID 1/ p" execute from the first line until your pattern and p (print)
  • -e "/\$ description 1/,$ p" execute from the second pattern until the end and p (print).

I might be wrong with some of the escaping on the strings, so please double check.

ReferenceURL : https://stackoverflow.com/questions/6287755/using-sed-to-delete-all-lines-between-two-matching-patterns

반응형