내 입력 파일은 다음과 같습니다.
START
line1
line2
line3
END
START
line11
line22
line33
END
내 스크립트가 다음과 같이 출력되기를 원합니다.
START line1 line2 line3 END
START line11 line22 line33 END
도와주세요.
답변1
사용 awk
:
$ awk '{printf "%s", $0 (($0 == "END") ? ORS : OFS)}'
START
에서 까지 줄을 서려면 END
다음을 사용할 수 있습니다.
$ awk '($0 =]"START"),($0 == "END"){printf "%s%s",$0, ($0=="END" ? ORS : OFS)}'
그렇지 않은 경우 다음 명령을 사용할 수 있습니다 START
.END
$ awk '($0 == "START"){a="";} {a = a $0 (($0 == "END") ? "" : OFS)} ($0 == "END"){print a}'
답변2
다중 문자에는 GNU awk를 사용 RS
하고 RT
다음 예와 같이 데이터에 항상 완전하고 중첩되지 않으며 겹치지 않는 START-END 블록이 있다고 가정합니다.
$ awk -v RS='\nEND\n' -F'\n' '{$0=$0 RT; $1=$1} 1' file
START line1 line2 line3 END
START line11 line22 line33 END
START-END 블록 외부에 행을 추가할 수 있는 경우 대신 다음을 수행하십시오.
$ awk -v RS='\nEND\n' -F'\n' 'RT{$0=gensub(/.*\n(START\n)/,"\\1",1) RT; $1=$1; print}' file
START line1 line2 line3 END
START line11 line22 line33 END
또는 awk를 사용하십시오.
$ awk '
$0 == "START" { f=1; rec=$0; next }
f { rec=rec OFS $0; if ( $0 == "END" ) { print rec; f=0 } }
' file
START line1 line2 line3 END
START line11 line22 line33 END
중첩되거나 겹치거나 불완전한 START-END 블록이 있고 위에서 원하는 대로 작동하지 않는 경우 이러한 요구 사항을 표시하도록 질문을 편집해야 합니다.
답변3
사용 sed
:
$ sed -n -e '/^START$/ { h; d; }' -e H -e '/^END$/ { g; y/\n/ /; p; }' file
START line1 line2 line3 END
START line11 line22 line33 END
스크립트 sed
는 주석과 함께 보기 좋게 인쇄됩니다.
# Save each "START" line in the hold space and skip to the next line.
/^START$/ {
h
d
}
# Append all non-"START" lines to the hold space.
H
# On an "END" line, get the hold space, convert newlines to spaces, and print.
/^END$/ {
g
y/\n/ /
p
}
이는 "START" 및 "END" 행의 범위가 겹치지 않고 "END"와 "START" 사이에 추가 데이터가 없다고 가정합니다.
답변4
사용행복하다(이전 Perl_6)
END
한 레코드와 다음 레코드 사이(예: 및 사이 ) 의 중간 행을 삭제하려면 START
:
~$ raku -ne 'S/ <!after END> $/ / andthen do if /^START/ fff s/^END$/END\n/ {.print};' file
또는:
~$ raku -ne 'S/ <!after END> $/ / andthen print ($_ if /^START/ fff s/^END$/END\n/) ;' file
위의 내용은 Raku 프로그래밍 언어로 코딩된 답변입니다. 즉, -ne
명령줄 플래그는 자동 인쇄 없이 입력 파일에서 코드를 한 줄씩 실행하는 데 사용됩니다. 단어로 끝나지 않는 각 줄에 대해 S///
"big-S" 대체 연산자를 사용하고 (부정적 뒤돌아보기) 공백을 추가합니다. 이 단계를 사용하면 사이에 공백이 있는 줄을 쉽게 연결할 수 있습니다(참고: @Kusalananda가 댓글에 게시한 것과 유사한 답변을 얻는 데 사용됨).<!after END> $
END
\t
계속해서 $_
테마 변수 다시 로드를 사용하세요 andthen
. 이제 Raku의 sed와 유사한 /START/ fff /STOP/
"트리플 f" 트리거 연산자를 사용하여 원하는 센티넬 라인 사이의 라인을 캡처할 수 있습니다. 형식 지정 트릭에서 실제로 동일한 트리거 연산자 의 센티넬 라인을 s/^END$/END\n/
대체하고 그 뒤에 줄바꿈을 추가 할 수 있습니다 .END
fff
\n
END
마지막으로 출력은 print
자체 개행 문자를 추가하지 않고 위의 공백/개행 형식을 유지하는 Raku의 간단한 연산자를 통해 수행됩니다.
입력 예:
START
line1
line2
line3
END
test
START
line11
line22
line33
END
출력 예(가운데 줄 제거):
START line1 line2 line3 END
START line11 line22 line33 END
자, 어떻게 하면 중간선을 지킬 수 있을까요? 간단합니다. fff
Raku의 "whatever-star"를 사용하여 모든 출발선을 허용 하도록 트리거 연산자를 변경하기만 하면 됩니다 . *
아래를 참조하세요:
~$ raku -ne 'S/ <!after END> $/ / andthen do if * fff s/^END$/END\n/ {.print};' file
START line1 line2 line3 END
test START line11 line22 line33 END
#OR
~$ raku -ne 'S/ <!after END> $/ / andthen print ($_ if * fff s/^END$/END\n/);' file
START line1 line2 line3 END
test START line11 line22 line33 END
https://docs.raku.org/syntax/S%2F%2F%2F%20Non-destructive%20replacement
https://docs.raku.org/routine/fff
https://docs.raku.org/routine/andthen
https://raku.org