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
( p
0인 경우 이전 행 유지).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
...빈 첫 번째 줄도 처리합니다(이전 입력이 없으므로 무시함).