다음과 같은 형식의 파일이 있습니다.
title1
line
line
title2
line
line
line
title3
line
line
아래 섹션을 추출하고 들여쓰기를 제거하고 싶습니다 title2
. 나는 현재 다음과 같이 사용하고 있습니다 sed
(그러나 awk
쉘 스크립트는 내 상황에 적합하지만 슬프게도 perl
또는 같은 언어는 아닙니다).python
sed -n -e '/^title2$/,/^[a-zA-Z]/ { /^[a-zA-Z]/ d ; s/^[ \t]*// ; p }'
그러나 그러면 끝에 논리적으로 빈 줄이 남게 됩니다(논리적으로는 공백이나 탭이 있을 수 있기 때문입니다). 나는 그것을 제거하고 싶다. 유지해야 할 부분에 논리적으로 다른 빈 줄이 있을 수 있습니다(또는 /^[ \t]*$/ d
작업을 수행했을 수 있음). 따라서 나는 다음과 같은 결과를 원합니다.
line
line
line
추가로 할 수 있지만 sed -e '$d'
두 번째 프로세스를 피할 수 있는지 알고 싶습니다.
답변1
나는 홀드 공간을 이용했고 결국
sed -ne '/^title2$/,/^[a-zA-Z]/ { /^title2$/ { n; h; b; } ; /^[a-zA-Z]/ d; H; x; s/[ \t]*//; P; s/.*\n//; x }'
내가 돌보는 사건을 올바르게 처리하는 것 같습니다.
답변2
- "순수한" 줄(탭이나 흰색 없음)인 경우 다음을 사용하여 삭제하세요.
/^$/
"논리적" 공백 사용을 위해
/^\s*$/
sed -n -e '/^title2:/,/^[a-zA-Z]/ { /^[a-zA-Z]/ d ; /^$/ d ; s/^[ \t]*// ; p }'
어디
/^$/
시작줄, 끝줄 일치/^\s*$/
시작 줄 일치, 0개 이상의 공백 또는 탭, 줄 끝 일치
답변3
sed -n '/title2/,/^\S/ { //b; /^\s*$/ { N; /\n\S/q; P; D }; s/^\s*//; p }'
나는 처음에 @Archemar의 관심을 끌기 위해 이렇게 했습니다. 해주시면 정말 감사하겠습니다제발답장하다이 글에 달린 내 댓글시간이 있을 때마다. 대답이 "모른다"라고 하더라도. 감사해요.
내 bash 쉘에서는 적어도 -e
. 왜 필요한지 궁금하십니까? 그리고 만약에\s
또는\S
[ \t]
지원되지 않는 경우 각각 ' 및 [^ \t]
' 로 바꿀 수 있습니다 .
이 질문을 처음 봤을 때 저처럼 아무것도 모르는 사람들을 위한 분석:
-n
자동 인쇄를 끕니다/title2/,/^\S/
검색할 범위sed
(문자열 "title2
"이 처음 나타나는 줄부터 공백이 아닌 문자[즉title3
] 로 시작하는 다음 줄까지)포괄적으로){
단지 내가 방금 지정한 범위나 패턴에 동봉된 명령을 적용한다는 의미입니다.//b
다음 명령이 범위의 시작과 끝 부분에 적용되지 않도록 허용합니다.
더 말 그대로, 스크립트 끝으로 일치하거나 분기하면(title2
) (파일에 남은 줄이 있으면 다음 줄을 처리합니다)^\S
b
암소 비슷한 일종의 영양sed
(BSD비슷하게 말하는데, 다른 버전이 있는지는 확실하지 않습니다sed
)'//'는 마지막 정규식 일치를 반복합니다.
/^\s*$/
범위의 "논리적으로 비어 있는" 행과 일치합니다.{
N; /\n\S/q;
따라서 "논리적으로 공백" 행인 경우N
패턴 공간에 다음 행을 추가하고 그 다음 행이 다음 제목이면 처리를 모두 중단하므로(q
) "논리적으로 공백" 행도 다음 제목도 모두 포함되지 않습니다. 인쇄되었습니다.P; D
"논리적으로 비어 있는" 줄인 경우그렇지 않다그 다음에는 다음 제목, 그 다음에는단지"논리적으로 공백" 줄이 인쇄됩니다(P
).단지N
"논리적으로 공백" 라인은 패턴 공간에서 삭제되고 스크립트 시작 부분부터 처리되도록 패턴 공간에 추가된 다음 라인이 남습니다 (D
).
}
s/^\s*//; p
줄 시작 부분의 공백과 탭을 제거하고 서식이 지정된 줄을 인쇄합니다.
}
@Archemar 부탁드려요돕다