파일이 있습니다. 내용은 다음과 같습니다.
cat -n /tmp/my_file
1 verify(abc) {
2 foo : bar;
3 sub1(aa) {
4 line1;
5 }
6 sub2 (bb) {
7 line1;
8 // this line is a comment and must be ignored
9 line2;
10 sub3 (cc) {
11 line1;
12 }
13 }
14 }
15
16 verify(efg) {
17 foo : bar;
18 sub1(aa) {
19 line1;
20 }
21 sub2 (bb) {
22 line1;
23 // this line is a comment and must be ignored
24 line2;
25 sub3 (cc) {
26 line1;
27 }
28 }
29 }
(줄 번호는 설명 목적으로만 사용되며 파일의 일부가 아닙니다.)
콘텐츠를 다음 형식으로 변환하려면 awk 또는 Perl을 사용해야 합니다.
verify(abc) { foo : bar; sub1 (aa) { line1; } sub2 (bb) { line1; line2; sub3 (cc) { line1; } } }
verify(efg) { foo : bar; sub1 (aa) { line1; } sub2 (bb) { line1; line2; sub3 (cc) { line1; } } }
어떻게 해야 하나요?
답변1
한 줄:
awk '{ if ( NF > 0 && $1 !~ /^\/\// ) { bl=0; for (i=1;i<=NF;i++) printf "%s ", $i }; ( NF == 0 && bl == 1 ) {printf "\n" }; if ( NF == 0 && bl == 0 ) {bl=1; printf "\n\n" } } END { if ( bl == 0 ) { printf "\n" } } ' /tmp/my_file
설명하다:
if ( NF > 0 && $1 !~ /^\/\// ) { bl=0; for (i=1;i<=NF;i++) printf "%s ", $i }
필드 수가 0보다 크고 첫 번째 필드가 주석이 아닌 경우 해당 필드와 각 필드에 대한 공백을 인쇄합니다. 정규식은 실제로 "^//"("//"로 시작)이지만 "/"는 이스케이프되어야 하므로 "\/"가 됩니다. 또한 bl=0은 이전 빈 줄 플래그를 설정합니다. 이 플래그는 나중에 명령문에서 레코드 끝/빈 줄 핸들을 제어하는 데 사용할 것입니다.
다음으로, 빈 줄/레코드 끝 상황을 처리합니다.
먼저 이것이 빈 줄인지 확인하십시오.
if ( NF == 0 && bl == 1 ) {printf "\n" };
필드 수가 0이고 이전 빈 줄 플래그가 설정된 경우 개행 문자만 인쇄됩니다.
다음으로 데이터/텍스트 줄을 방금 끝냈고 다른 줄을 추가해야 하는지 테스트합니다.
if ( NF == 0 && bl == 0 ) {bl=1 printf "\n\n" }
필드 수가 0이고 이전 빈 줄 플래그가 설정되지 않은 경우 빈 줄 플래그가 설정되고 줄의 끝이 인쇄됩니다.
마침내! ! !
END { if ( bl == 0 ) { printf "\n" } }
파일이 완성되면 레코드 줄 종결자가 인쇄되는지 확인하고, 그렇지 않으면 인쇄합니다.
답변2
각 블록(각 "verify()" 루틴)은 한 줄로 시작 verify
하고 한 줄로 끝난다 }
(그리고 줄이 없다고 가정합니다).이내에루틴은 }
)로 시작하고 모든 공백은 공백입니다.
전임자
printf '%s\n' 'g|^ *//|d' 'g/^verify/.,/^}/j' x | ex -- /tmp/my_file
ex
(명령줄 버전 / )을 사용하여 vi
파일을 편집합니다 vim
.
g|^ *//|d
정규식과 일치하는 모든 줄을 찾아서^ *//
(즉,//
0개 이상의 공백을 포함하고 그 외에는 아무것도 포함하지 않음) 삭제합니다.g/^verify/.,/^}/j
정규식과 일치하는^verify
(즉, 로 시작하는 ) 모든 줄을 찾습니다verify
. 그런 다음 각각에 대해 정규식과 일치하는 첫 번째 줄^}
(예: 로 시작}
) 을 찾고제이verify
oins와}
(inclusive) 사이의 모든 줄에서 압착된 개행 문자 앞뒤의 추가 공백은 삭제됩니다.x
저장 및 종료.
노트:입력 파일을 덮어쓰게 됩니다.
sed
sed -n '/^verify/ { h; d }; /^ *\/\//d; /./H; /^}/ { g; s/ *\n */ /gp }; /^$/p' /tmp/my_file
-n
— 지시가 없는 한 인쇄하지 마십시오./^verify/ { h; d }
— 로 시작하는 줄이 보이면verify
이를 다음 위치에 복사하세요.시간오래된 공간과디패턴 공간을 제거합니다(즉, 추가 처리 없이 다음 입력 줄로 계속 진행)./^ *\/\//d
— 0개 이상의 공백으로 시작하는 줄 합계가 보이면//
삭제하세요(즉, 추가 처리 없이 다음 입력 줄로 계속 진행)././H
— 위 이외의 비어 있지 않은 줄은 예약된 공간에 추가합니다./^}/ { g; s/ *\n */ /gp }
}
— 다음으로 시작하는 줄을 볼 때G보유 공간을 패턴 공간으로 설정합니다. 그런 다음 포함된 각 줄 바꿈 문자(및 이전 및 다음 공백)를 단일 공백으로 바꿔 단일 라인으로 압축한 다음 인쇄합니다./^$/p
— 빈 줄을 인쇄합니다.
앗
awk '
/^ *\/\// { next; }
/./ { buffer = buffer " " $0; }
/^}/ { sub(/^ */, "", buffer); sub(/ *$/, "", buffer);
gsub(/ * /, " ", buffer); print buffer; buffer = ""; }
/^$/ { print; }
' /tmp/my_file
- 댓글을 보시면 건너뛰세요.
- 비어 있지 않은 다른 모든 줄을 에 연결합니다
buffer
. 줄 바꿈은 암시적으로 삭제됩니다. - 로 시작하는 줄이 보이면
}
그 안에 있는 추가 공백을 모두 제거하고buffer
인쇄한 후 지우세요. - 빈 줄을 인쇄합니다.