다음 패턴까지 이 패턴 뒤의 두 줄마다 병합

다음 패턴까지 이 패턴 뒤의 두 줄마다 병합

파일.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

관련 정보