sed

sed

쓸모없는 정보가 제거된 거대한 cvs 로그 파일이 있고 내용은 다음과 같습니다.

Working file: unmodifiedfile1.c
================
Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: unmodifiedfile2.h
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================
Working file: unmodifiedfile3.h

수정되지 않은 파일과 관련된 줄을 정리하고 싶습니다.

Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================

어울리는 패턴은

Working file: FILENAME
================

지금까지 내가 할 수 있었던 일은 다음과 같습니다.

sed '/Working file:/ N ; s/\n/PLACEHOLDER/' changelog.txt |
grep -v 'PLACEHOLDER===' |
sed 's/PLACEHOLDER/\n/ 

하지만 더 깨끗한 해결책이 있다고 확신합니다. sed에 대한 무지가 저를 막고 있습니다... (또한 추가 보너스는 필요한 경우 최신 줄을 삭제할 수 있다는 것입니다)

폴리스티렌

출력은 다음으로 끝납니다.

================
Working file: unmodifiedfile3.h

또한 허용

답변1

sed

이것은 당신이 추구하는 것과 비슷해야 합니다:

<cvslog sed -n '/Working file/ { N; /\n=\+$/b; :a; N; /\n=\+$/!ba; p; }'

산출:

Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================

설명하다

다음은 주석이 포함된 동일한 스크립트입니다 sed.

/Working file/ {
  N                 # append next line to pattern space
  /\n=\+$/b         # is it a file separator -> next file
  :a
  N                 # append next line to pattern space
  /\n=\+$/!ba       # isn't it a file separator -> read next line
  p                 # otherwise print accumulated text
}

awk파일 구분선을 레코드 구분선( )으로 사용하도록 지시하면 RS합리적인 선택 기준을 정의하는 것이 매우 간단해집니다.

<cvslog awk 'NF>2' RS='\n=+\n' FS='\n' ORS='\n\n'

산출:

Working file: modifiedfile1.h  
----------------------------------
revision 1.3
Fixed some bug

Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature

bash 및 coreutils

재미로:

csplit cvslog '/=\{16\}/1' '{*}'
wc -l xx* | 
head -n-1 | 
while read n f; do 
  if (( n > 2 )); then 
    cat $f
  fi
done

산출:

Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================

답변2

sed '/Working file:/ N ; s/\n/PLACEHOLDER/' changelog.txt |
grep -v 'PLACEHOLDER===' |
sed 's/PLACEHOLDER/\n/ 

실제로 다음과 같이 단축할 수 있습니다.

$ sed '/Working file:/{N;/===/d}' changelog.txt 
Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================
Working file: unmodifiedfile3.h


  • Working file:다음 줄(포함된 경우) ===과 마지막 줄(포함된 경우)을 포함하는 모든 줄을 삭제합니다 .Working file:

제안해 주신 @ilkkachu에게 감사드립니다. 패턴이 줄 시작 부분에서 일치해야 하는 경우 다음을 사용하세요.^Working file:

$ cat ip.txt 
Working file: 123
================
Working file: f1
----------------------------------
revision 1.3
Fixed some bug
================
Working file: abc
================
Working file: file
----------------------------------
revision 1.1
Added some feature
================
Working file: xyz

$ sed '/Working file:/{N;/===/d}' ip.txt | sed '${/Working file:/d}' 
Working file: f1
----------------------------------
revision 1.3
Fixed some bug
================
Working file: file
----------------------------------
revision 1.1
Added some feature
================

관련 정보