빈 줄을 위의 내용으로 교체

빈 줄을 위의 내용으로 교체

Linux 컴퓨터에서 탭으로 구분된 텍스트 파일의 빈 줄을 위 줄의 내용으로 바꾸는 방법은 무엇입니까? 예를 들어:

101 abc group1
765 efg group2
345 hij group4

456 gfd group9
762 ert group7


554 fgt group11

예상 출력:

101 abc group1
765 efg group2
345 hij group3
345 hij group3
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11

답변1

다음은 한 가지 방법입니다 awk( p0인 경우 이전 행 유지).NF

awk 'NF {p = $0} {print p}' file

p행이 비어 있지 않으면 나중에 사용할 수 있도록 행을 저장 하고 인쇄합니다 p.

(빈 줄의 경우 NF==0) 우리는 p.

답변2

In awk(이렇게 하면 비어 있지 않은 첫 번째 줄 앞에 모든 빈 줄이 인쇄됩니다):

$ awk '{ if(! NF){$0=last}else{last=$0;}}1' file
101 abc group1
765 efg group2 
345 hij group4 
345 hij group4 
456 gfd group9 
762 ert group7 
762 ert group7 
762 ert group7 
554 fgt group11  

설명하다:

NF저장된 필드 수. 행이 비어 있으면 필드가 없으므로 변수는 가 됩니다 0.

  • if(! NF){$0=last}: 필드 수가 0(빈 행)인 경우 현재 행( $0)이 변수의 값으로 설정됩니다 last.
  • else{last=$0;}: 필드가 있는 경우 이 행은 비어 있지 않으며 last이 행의 내용을 저장하도록 설정됩니다.
  • 1:끝에 있는 유일한 것은 awk 트릭입니다. 어떤 것이 true로 평가되면(0은 false이므로 1 또는 0보다 큰 다른 정수는 항상 true입니다) awk는 현재 행을 인쇄합니다. 1따라서 이는 print $0.
$ awk '! NF ? $0=last : last=$0;' file
101 abc group1
765 efg group2 
345 hij group4 
345 hij group4 
456 gfd group9 
762 ert group7 
762 ert group7 
762 ert group7 
554 fgt group11  

설명하다 이는 위와 같은 개념이지만 좀 더 간결하게 작성되었습니다. 우리는 사용하고 있습니다삼항 연산자. 두 조건 중 하나가 항상 참이므로( NF참이든 아니든, 삼항 연산자는 항상 참을 반환합니다), 두 조건 모두 인쇄되는 줄이 됩니다(줄이 비어 있고 빈 줄이나 줄에 표시되지 않는 항목이 없는 한). ) 로만 구성됩니다 0. 그러나 NF설정되어 있지 않으면 설정하고 $0, last설정되어 있으면 설정 last합니다 $0. 결과는 우리가 원하는 결과입니다.

위의 내용은 줄만 인쇄하지 않으므로 0문제가 되는 줄 대신 이것을 사용할 수 있습니다.

awk '{! NF ? $0=last : last=$0};1' file

답변3

제공된 입력을 사용하고 다음을 수행하십시오 sed.

$ sed -n '/^$/{g;};h;p' infile
101 abc group1
765 efg group2
345 hij group4
345 hij group4
456 gfd group9
762 ert group7
762 ert group7
762 ert group7
554 fgt group11 
$

참고: '/^$/{g;};h;p'분명히 그것은 '/^$/g;h;p'Just my style로 더 일반적으로/정확하게 작성됩니다.

guest_7지적했듯이(감사합니다) 명령 sed은 다음과 같이 더 간단하게 작성할 수도 있습니다.sed '/^$/g;h' infile

지적 했듯이 terdon, 제가 처음에 생각하지 못한 것은 "빈" 줄에 공백이나 탭(공백)이 포함될 수 있다는 것입니다. 이 경우 보다 안정적인 솔루션은 다음과 같습니다.

$ sed '/^\s*$/g;h' infile

다양한 로케일을 지원하는 보다 이식성이 뛰어난 솔루션은 다음과 같습니다.

$ sed '/^[[:blank:]]*$/g;h' infile

답변4

기존 답변에 추가:

awk 'NR<2 && !NF{next} NF{print} !NF{print line} NF{line=$0}' test

...빈 첫 번째 줄도 처리합니다(이전 입력이 없으므로 무시함).

관련 정보