한 번의 sed
호출로 두 경우 (단일 연속 블록에서 주석 처리 된 행 또는 주석 처리되지 않은 행에 산재 된)를 처리 할 수 있습니다 .
sed '1,/PATTERN/{/^#/{x;1d;b};//!{H;/PATTERN/!{1h;d};//{x;s/\n/&#/g}}}' infile
1,/PATTERN/
범위 내의 라인 만 처리합니다 . 그것은 전자 x
의 변화가 w 공간을 누릅니다. 행이 주석 처리 될 때마다 패턴 공간 (따라서 보류 버퍼에 주석 처리 된 행이 두 개 이상 존재하지 않음)하고 H
이전 공간에 주석 처리되지 않은 모든 행을 추가 합니다 (첫 번째 행에있을 때 1d
각각 1h
초기 행을 제거해야 함) 홀드 버퍼의 빈 줄).
PATTERN과 일치하는 행에 도달하면 H
이전 버퍼 에도 추가하고 , e x
는 버퍼를 변경 한 다음 \n
패턴 공간의 모든 ewline 문자를 \n
ewline과 a 로 바꿉니다 #
(즉, 패턴 공간의 모든 행은 이제 #
, 보류 공간에서 첫 번째 행으로 첫 번째 행을 포함하는 것은 항상 주석 처리 된 행입니다).
샘플 infile
:
alice
#bob
bill
#charlie
ding
dong
dotan
jimmy
#garry
달리는:
sed '1,/dotan/{ # if line is in this range -start c1
/^#/{ # if line is commented -start c2
x # exchage hold space w. pattern space
1d # if 1st line, delete pattern space
b # branch to end of script
} # -end c2
//!{ # if line is not commented -start c3
H # append to hold space
/dotan/!{ # if line doesn't match dotan -start c4
1h # if 1st line, overwrite hold space
d # delete pattern space
} # -end c4
//{ # if line matches dotan -start c5
x # exchage hold space w. pattern space
s/\n/&#/g # add # after each newline character
} # -end c5
} # -end c3
}' infile # -end c1
출력 :
alice
#bob
bill
#charlie
#ding
#dong
#dotan
jimmy
#garry
그래서 그것은 (그리고 제외)에서 ( #charlie
포함하는) 줄까지 주석 처리 dotan
하고 다른 줄은 그대로 둡니다.
물론 이것은 일치하는 줄 앞에 항상 적어도 하나의 주석 처리 된 줄이 있다고 가정합니다 PATTERN
. 그렇지 않은 경우 교체 전에 추가 검사를 추가 할 수 있습니다./^#/{s/\n/&#/g}