주석이 달린 구성 파일을 업데이트하기 위해 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에서 빈 줄은 독단적입니다.