sed를 사용하여 두 개의 빈 줄 앞에 텍스트를 삽입하십시오.

sed를 사용하여 두 개의 빈 줄 앞에 텍스트를 삽입하십시오.

주석이 달린 구성 파일을 업데이트하기 위해 sed를 사용하려고 합니다. 모든 것을 EOF에 두는 대신 모든 것을 별도로 유지하려고 노력합니다. 내 구성은 다음과 같습니다.

# SECTION ONE
data...
data...
data...
<insert line here>

# SECTION TWO
data...
data...

첫 번째 섹션 끝에 줄을 삽입하려고 하는데 "\n"을 허용하지 않고 패턴에 여러 개의 "^$"를 포함할 수 없기 때문에 검색 패턴을 작성하는 데 문제가 있습니다. 나는 다음과 같은 것을 원합니다 :

sed -i "/^\n\n# SECTION TWO.*/i data..." somefile.conf

    or

sed -i "/^$^$# SECTION TWO.*/i data..." somefile.conf

다른 제안도 환영하지만 가능하다면 한 줄로 유지하고 싶습니다. 이것은 더 큰 스크립트의 일부입니다. Python, Perl 등을 사용하는 것이 매우 쉽다는 것을 알고 있지만 이것을 "쉘" 솔루션으로 유지하려고 합니다.

답변1

awk대신 사용하십시오 sed:

newdata='This is the new data'

newdata=$newdata awk -F '\n' -v OFS='\n' -v RS= -v ORS='\n\n' \
    '$1 == "# SECTION ONE" { $(NF+1) = ENVIRON["newdata"] }; 1' file

또는

newdata='This is the new data'

newdata=$newdata awk '
    BEGIN { FS = OFS = "\n"; RS = ""; ORS = "\n\n" }
    $1 == "# SECTION ONE" { $(NF+1) = ENVIRON["newdata"] }; 1' file

awk입력 레코드 구분 기호에 null 값을 사용하여 "단락 읽기 모드"로 들어갑니다 . RS즉, awk한 번에 한 단락씩 읽게 됩니다. "단락"은 하나 이상의 빈 줄로 구분된 줄 모음입니다.

그런 다음 입력 필드 구분 기호를 FS개행 문자로 설정하여 -F '\n'단락의 각 줄이 자체 필드가 ​​되도록 합니다.

또한 레코드(문단)는 후행 공백 줄로 출력되고 필드(단락 내 줄)는 개행 종료로 출력되도록 ORS출력 과 관련된 해당 변수를 설정합니다 .OFS

실제 코드는 단락의 첫 번째 줄이 정확히 문자열인 경우를 감지합니다 # SECTION ONE. 이 경우 새 데이터가 포함된 현재 레코드의 끝에 새 필드가 추가됩니다. 새 데이터는 newdata환경 변수에서 가져옵니다.

수정 여부와 관계없이 모든 문단은 무조건 출력됩니다.

만약에 참고하세요실제질문에서 볼 수 없는 구성 파일은 XML, YAML, JSON 또는 기타 구조화된 문서 형식으로 작성되며, 대답은 다음과 같습니다.유효하지 않은, 해당 문서 형식과 같은필요하다읽기 및 쓰기를 위한 적절한 형식 인식 도구(행 지향이 아니고 데이터를 인코딩/디코딩해야 하기 때문)

답변2

GNU sed를 사용하면 다음을 수행할 수 있습니다.

sed -e '/# SECTION ONE/,/^$/s/^$/__NEW-DATA__\n/' file

awk의 범위 연산자를 사용하여 원하는 출력을 얻을 수 있습니다.

awk '
  /# SECTION ONE/,!NF{
    if (!NF) print "__NEW-DATA__"
  }1
' file

이 방법은 POSIXly sed 구성을 사용합니다.

sed -e '
  /# SECTION ONE/!b
  :a
    n;/^$/!ba
  G;s/^/__NEW-DATA__/
' file

이 방법에서는 첫 번째 데이터가 아닌 경우 섹션 이름 앞에 새 데이터를 배치합니다. 파일 크기가 3줄 이상이라고 가정합니다.

sed -e '
  1,2N
  $q;N
  s/^\n\n# SECTION TWO/__NEW-DATA__\n&/;t
  P;D
' file

답변3

쿠살란드라스의 댓글과 질문을 다시 읽어보니 그 사람만큼 이해가 되네요.

GNU-sed에는 POSIX 스타일을 켜는 스위치가 있으므로 이번에는 이 명령이 sed 스타일과 관련이 없기를 바랍니다.

원본 파일:

cat FILE
# SECTION ONE
data...
data...
data...

# SECTION TWO
data...
data...

주문하다:

sed --posix "s/^[ \t]*$/...new data .../; /# SECTION TWO/i\\ " FILE

# SECTION ONE
data...
data...
data...
...new data ...
 
# SECTION TWO
data...
data...

삽입하면 파일에 공백이 남게 되는데, 이는 후속 sed 명령으로 제거할 수 있거나 s/^[ \t]*$정규식으로 useind를 통해 처리할 수 있습니다. 이는 공백 및/또는 탭에 대한 순수 공백뿐만 아니라 빈 줄과도 일치합니다.

선택하다:

sed --posix "s/^$/...new data .../; /# SECTION TWO/i\ " -e "s/^ $//" FILE 

두 번째 형식은 두 번째 sed 명령(-e - 두 개의 명령을 사용한 후 첫 번째 따옴표로 구분된 세 번째 명령이라고 가정 ;)을 사용하여 공백을 제거합니다(허용되지 않는 경우). 따라서 find에서 빈 줄은 독단적입니다.

관련 정보