파일.txt
String1?
word1
word2
word3
word4
String2?
word5
word6
word7
word8
원하는 출력:
String1?
word1 | word2
word3 | word4
String2?
word5 | word6
word7 | word8
내가 시도한 유일한 패턴은 line 입니다 /?$/
.
sed '/\?$/{n;:l N;/\?$/b; :a; N; $!b a; s/\n\s\{1,\}/ | /g; bl}'
그러나 그것은 작동하지 않았습니다. 내 현재 작업 솔루션:
sed '/\?$/{:a;N;/\n....-..-.. /!s/\n/ - /;ta;P;D}' | sed 's/^[- ]*//g;s/[ -]*$//g'
...하지만 해결 방법이고 속도가 매우 느립니다. 파이프가 없는 단일 라이너와 빠른 솔루션으로 도움을 줄 수 있는 사람이 있습니까?
패턴과 같이 빈 줄이 없고 ,$\|^$
^$가 존재하지 않고 ?$가 포함된 다른 줄이 있는 경우 어떻게 ?$에서 탐욕스럽지 않은 첫 번째 ?$ 패턴까지 버퍼를 저장한 다음 마지막 All을 제외하고 인쇄할 수 있습니까? 한 줄만 검색하고 마지막 줄을 다음 패턴 버퍼와 병합하여 검색하시겠습니까?
답변1
GNU sed 전용입니다.
블록의 모든 행에 정확히 2개의 열이 있는 경우(귀하의 경우):
sed '/?$\|^$/b;N;s/\n/ | /' File.txt
이상한 콘텐츠가 가능한 경우(일반적인 방식):
sed '/?$\|^$/b;N;/\n$/!s/\n/ | /' File.txt
답변2
입력 예에 표시된 것처럼 입력이 빈 줄로 구분된 텍스트 블록이라고 가정하면 모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ awk -v RS= -F'\n' -v OFS=' | ' '{print $1; for (i=2; i<NF; i+=2) print $i, $(i+1); print ""}' file
String1?
word1 | word2
word3 | word4
String2?
word5 | word6
word7 | word8
답변3
$ sed '/?$/,/^$/ { //b; N; y/\n/|/; }' file
String1?
word1|word2
word3|word4
String2?
word5|word6
word7|word8
행 범위의 경우 끝에 a가 있는 행 /?$/,/^$/
부터 빈 행까지:?
- 현재 행이 범위의 첫 번째 또는 마지막 행인 경우 아무 작업도 수행하지 않습니다(
//b
; "(이 루프에서) 가장 최근에 일치한 정규 표현식이 일치하면 스크립트 끝으로 분기합니다."). - 그렇지 않으면 다음 입력 줄을 버퍼(
N
)에 추가하고 삽입된 개행 문자를 한 문자로 바꿉니다|
. 파이프 주위에 간격을 두려면s/\n/ | /
대신 를 사용하십시오y/\n/|/
.
POSIX 방식:
sed -e '/?$/,/^$/ { //b' -e N -e 'y/\n/|/' -e '}' file
또는 여기 문서를 통해 제공되는 별도의 스크립트 파일을 사용하세요.
sed -f /dev/stdin file <<'END_SED'
/?$/,/^$/ {
// b
N
y/\n/|/
}
END_SED
와 같은 것 awk
,
awk -v OFS='|' '
/\?$/,length == 0 {
if ( !/\?$/ && length != 0) {
getline n
print $0, n
} else print
}' file
/^$/
출력에서 파이프 구분 기호 주위에 공백이 필요한 경우 위의 코드를 length == 0
대신 사용할 수도 있습니다 OFS=' | '
.OFS='|'
답변4
Perl 단락 모드(-00)에서는 다음을 수행할 수 있습니다.
perl -aF'\n' -nls -00e '
print shift @F;
print splice(@F,0,2) while @F>1;
print @F if !eof;
' -- -,=" | " file
정규식 작성을 단순화하려면 확장 정규식 모드(-E)에서 GNU sed를 사용하십시오.
sed -E '
/./{H;$!d;}
x;$!G;s///
s/([^\n]*\n){2}/&|/g
s/\n\|/ | /g
' file