Input:
1:
aaa
bbb
2:
xxx
yyy,
zzz
3:
ccc
4:
5:
xxx
yyy
산출:
1: aaa bbb
2: xxx yyy, zzz
3: ccc
4:
5: xxx yyy
:$
요구 사항: 패턴 1과 패턴 2 사이의 모든 행을 병합합니다 :$
(패턴 1은 포함하지만 패턴 2는 포함하지 않음).
정규식 일치: :$
시도:
sed '/:$/{n;:l N;/:$/b; s/\n/ /; bl}' | sed '/:$/!b;/:$/N;/:$/!{s/\n//g}' -E
답변1
펄 사용:
$ perl -0 -pe 's/\n+/ /g;
s/ (\d+:)/\n$1/g;
s/^\n+//;
s/ +$/\n/' input.txt
1: aaa bbb
2: xxx yyy, zzz
3: ccc
4:
5: xxx yyy
(가독성을 위해 스크립트에 줄 바꿈이 추가되었습니다. 그대로 실행되거나 제거하여 읽을 수 없는 한 줄의 코드를 얻을 수 있습니다.)
- 첫째, 하나 이상의 줄 바꿈의 모든 인스턴스를 공백으로 바꿉니다(참고: 빈 줄을 제거/무시하는 추가적인 유용한 부작용이 있습니다).
- 그런 다음 모든 인스턴스의 공백을 바꿉니다.공백, 하나 이상의 숫자 및
:
개행 문자 포함. - 그런 다음 문자열 시작 부분의 모든 선행 줄 바꿈을 제거하고 문자열 끝의 모든 후행 공백을 단일 줄 바꿈으로 바꿉니다. 이는 이전 s/// 대체 작업이 모든 줄 바꿈을 공백으로 대체했기 때문에 필요합니다.
이 -0
옵션은 Perl이 입력 레코드 구분 기호로 NUL을 사용하도록 지시하며 입력에 NUL이 포함되어 있지 않기 때문에 전체 입력 파일을 하나의 긴 문자열로 처리하게 됩니다.
Perl에는 "읽기, 처리 및 자동 인쇄" 루프에서 전체 한 줄 스크립트를 래핑하는 -p
것과 같이 작동하도록 하는 옵션이 있습니다. sed
그런데 -n
Perl의 sed -n
옵션과 동일합니다("읽기, 처리하지만 자동으로 인쇄하지 않음" 루프).
man perlrun
이들 및 옵션에 대한 자세한 내용은 을 참조 -0
하십시오 .-p
-n
답변2
그리고 awk
:
$ awk -v ORS= '/:$/{print n; n="\n"; s=""} {print s $0; s=" "} END{print n}' ip.txt
1: aaa bbb
2: xxx yyy, zzz
3: ccc
4:
5: xxx yyy
-v ORS=
레코드 구분 기호에 대한 null 값 출력/:$/{print n; n="\n"; s=""}
- 처음에는 비어 있습니다
n
(첫 번째 줄 앞에 개행 문자가 인쇄되는 것을 방지하기 위해). s
일치하는 항목이 발견될 때마다 삭제됩니다.
- 처음에는 비어 있습니다
{print s $0; s=" "}
- 인쇄
s
후 입력 라인이 옵니다. s
다음으로 끝나지 않는 줄에만 공백 문자 사용:
- 인쇄
답변3
"크기 조정 가능한" 슬라이딩 창을 사용할 수 있습니다. $!N
일반적으로 여기에서만 P
조건부 D
로 수행해야 합니다. 패턴 공간에 줄을 축적하고 패턴 공간이 일치하지 않을 때마다 개행을 공백으로 바꾸고, /:$/
그렇지 않으면 인쇄하고 개행으로 제거하고 반복합니다.
sed '/:$/{
:do
$!N;/:$/{
P;D
}
s/\
/ /
t do
}' infile
gnu sed
한 줄 구문을 선호하는 경우 :
sed '/:$/{:do;$!N;/:$/{P;D;};s/\n/ /;t do}' infile
답변4
tr 및 sed를 사용하는 것이 더 쉬울 수 있습니다.
$ tr '\n' ' ' <infile | sed 's/ [0-9]/\n&/g' | sed 's/^ //'
1: aaa bbb
2: xxx yyy zzz
3: ccc
4:
5: xxx yyy
(정렬이 문제가 되지 않으면 위 코드에서 두 번째 sed를 생략할 수도 있습니다)