이전 행에 행을 추가하는 방법은 무엇입니까?

이전 행에 행을 추가하는 방법은 무엇입니까?

구문 분석하고 분석해야 하는 로그 파일이 있습니다. 파일에는 다음과 유사한 내용이 포함되어 있습니다.

문서:

20141101 server contain dump
20141101 server contain nothing
    {uekdmsam ikdas 

jwdjamc ksadkek} ssfjddkc * kdlsdl
sddsfd jfkdfk 
20141101 server contain dump

위 내용을 토대로 이전 행에 추가해야 하는 날짜나 숫자가 시작 행에 포함되어 있지 않은지 확인해야 합니다.

결과물 파일:

20141101 server contain dump
20141101 server contain nothing {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdl sddsfd jfkdfk 
20141101 server contain dump

답변1

perl부정 예측을 사용하는 의 버전 :

$ perl -0pe 's/\n(?!([0-9]{8}|$))//g' test.txt
20141101 server contain dump
20141101 server contain nothing    {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdlsddsfd jfkdfk
20141101 server contain dump

-0정규식 교차 도메인 일치 허용전체 파일, \n(?!([0-9]{8}|$))는 줄 바꿈 문자 뒤에 8자리 숫자나 줄의 끝(사용된 경우 -0파일의 끝이 됨)이 뒤따르지 않음을 나타내는 부정 예측입니다.

답변2

조금 더 쉬울 수도 있어요sed

sed -e ':1 ; N ; $!b1' -e 's/\n\+\( *[^0-9]\)/\1/g'
  • 첫 번째 부분은 1개의 긴 줄로 :1;N;$!b1나눈 파일의 모든 줄을 수집합니다.\n

  • 두 번째 부분은 숫자가 아닌 문자 뒤에 공백이 있을 수 있는 경우 개행 문자를 제거합니다.

메모리 제한(특히 대용량 파일의 경우)을 방지하려면 다음을 사용할 수 있습니다.

sed -e '1{h;d}' -e '1!{/^[0-9]/!{H;d};/^[0-9]/x;$G}' -e 's/\n\+\( *[^0-9]\)/\1/g'

아니면 어려운 sed대본은 잊어버리고 그 해를 기억해 보세요.2

tr '\n2' ' \n' | sed -e '1!s/^/2/' -e 1{/^$/d} -e $a

답변3

한 가지 방법은 다음과 같습니다.

 $ perl -lne 's/^/\n/ if $.>1 && /^\d+/; printf "%s",$_' file
 20141101 server contain dump
 20141101 server contain nothing    {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdlsddsfd jfkdfk 
 20141101 server contain dump

그러나 .that은 마지막 개행 문자도 제거합니다. 다시 추가하려면 다음을 사용하세요.

$ { perl -lne 's/^/\n/ if $.>1 && /^\d+/; printf "%s",$_' file; echo; } > new

설명하다

후행 줄 바꿈을 제거 합니다 -l(또한 print각 호출에 1을 추가하므로 을 사용했습니다 printf. 그런 다음 현재 줄이 /^\d+/숫자( )로 시작하고 현재 줄 번호가 1( $.>1)보다 큰 경우 이 작업을 수행해야 합니다. 여분의 항목을 추가하지 말고(빈 줄은 개행으로 시작함) 각 줄의 시작 부분에 인쇄를 \n추가하세요 .printf


또는 \n모든 문자를 로 변경 \0한 다음 \0숫자 문자열 앞의 문자를 다시 다음으로 변경할 수 있습니다 \n.

$ tr '\n' '\0' < file | perl -pe 's/\0\d+ |$/\n$&/g' | tr -d '\0'
20141101 server contain dump
20141101 server contain nothing    {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdlsddsfd jfkdfk 
20141101 server contain dump

8자리 문자열만 일치시키려면 다음을 사용하십시오.

$ tr '\n' '\0' < file | perl -pe 's/\0\d{8} |$/\n$&/g' | tr -d '\0'

답변4

다른 답변보다 또 다른 가장 쉬운 방법은 다음을 사용하는 것입니다.그리고테든연산:

awk 'NR>1 && /^[0-9]{8}/{printf "%s","\n"$0;next}{printf "%s",$0}END{print}' file

관련 정보