공통 문자열 "Message"를 사용하여 특정 순서로 텍스트를 분할합니다.

공통 문자열 "Message"를 사용하여 특정 순서로 텍스트를 분할합니다.

다음 내용이 포함된 텍스트 파일이 있습니다.

$ cat foo.txt

some text 
[email protected]
8903457923
2018-02-09 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message
some text 
[email protected]
8903457923
2018-02-05 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message

다음 출력을 얻고 싶습니다.

$ cat foo.txt

some text  [email protected]  8903457923  2018-02-09 07:12 (Asia/Kolkata)  again some text over her  some more text again  Message

some text [email protected]  8903457923  2018-02-05 07:12 (Asia/Kolkata) again some text over here  some more text again  Message

나는 tr을 사용하고 "Message"를 일반 문자열로 사용하여 이를 달성할 수 있다고 생각합니다. 그러나 구현 방법을 잘 모르겠습니다.

답변1

현재 줄이 "Message"가 아닌 경우 목록에 줄을 추가하고 "Message"가 표시되면 OFS와 연결하여 현재 목록을 인쇄합니다(OFS로 현재 "Message" 줄과 연결됨).

awk '/^Message$/ { print t OFS $0 ORS; t=""; } !/^Message$/ { t=(t ? t OFS $0 : $0) }' < foo.txt

해당 t=(t ? t OFS $0 : $0)부분은 삼항 연산자입니다. tnull이면 현재 행이 할당되고, 그렇지 않으면 현재 값이 OFS에 추가됩니다.

산출:

some text  [email protected] 8903457923 2018-02-09 07:12 (Asia/Kolkata) again some text over here some more text again Message

some text  [email protected] 8903457923 2018-02-05 07:12 (Asia/Kolkata) again some text over here some more text again Message

답변2

AWK를 사용하는 더 쉬운 방법:

awk 'BEGIN { ORS=RS="Message\n" } gsub("\n"," ")' ./in.txt

답변3

사용 trsed:

tr '\n' '\t' <foo.txt  | sed -e $'s/Message\\\t/Message\\\n\\\n/g'

그러면 모든 개행 문자가 탭으로 변환되고 각 항목 다음에 두 개의 개행 문자가 추가됩니다.Message

답변4

가장 간단하고 직접적인 방법은 다음과 같습니다.

 perl -lpe '$\ = /^Message$/ ? "\n\n" : " "' foo.txt

아니면 awk다음과 같이 사용하세요:

 awk 'ORS = /^Message$/ ? RS RS : " "'

해당 파일을 빨아들인 다음 -0777전체 파일은 하나의 큰 문자열이 되고 정규식은 /(.*?)^(Message\n)/msg해당 파일에서 작동합니다. 정규 표현식은 라인에 인접한 가장 짧은 블록을 살펴보고 Message해당 블록을 에 저장 $1하고 nessage 라인을 에 저장합니다 $2. 블록은 전역적으로 공백으로 대체되는 개행 문자로 구성되며, 이 변환 결과는 tr/\n/ /r에 전달됩니다 print. while블록+메시지 라인이 발견되는 한 루프는 계속됩니다.

perl -ln -0777e 'print $1 =~ tr/\n/ /r, $2 while /(.*?)^(Message\n)/msg' foo.txt

sed도구를 사용하여 다음과 같이 이 작업을 수행할 수 있습니다.

sed -e '
    $!N;G;s/\n/ /                ;# put 2 lines in pattern space
    / Message\n$/b               ;# one message block has been found
    s/\(.*\)\(.\)/\2\1/;D        ;# go back to read the next line into pattern space
' foo.txt

관련 정보