awk를 사용하여 파일 끝의 빈 줄을 제거하는 방법은 무엇입니까?

awk를 사용하여 파일 끝의 빈 줄을 제거하는 방법은 무엇입니까?

다음을 사용하여 파일 끝에만 있는 빈 줄을 모두 제거하고 싶습니다.awk

다음 명령을 사용하여 상단의 빈 줄을 모두 제거하는 방법을 성공적으로 찾을 수 있었습니다.

awk '/^$/ && a!=1 {a=0} !/^$/ {a=1} a==1 {print}' file.txt

그러나 결론을 제거할 수 있도록 반전시키는 방법을 모르겠습니다. 위의 명령을 사용하여 파이프로 연결할 수 있다는 것을 알고 있지만 가능하다면 tac명령을 사용하는 직접적인 접근 방식을 선호합니다 .awk

명확히 하자면, "시각적으로 비어 있는" 줄, 즉 최대 공백 및/또는 탭을 포함하는 줄은 "빈" 것으로 간주됩니다.

답변1

awk는 외부 도움(예: Tac) 없이 첫 번째 줄부터 마지막 ​​줄까지 순차적으로 파일을 읽기 때문에 실제로 파일 끝에 도달했을 때 빈 줄 블록이 파일 끝에 있는지 여부만 알 수 있습니다.

당신이 할 수 있는 일은 빈 줄(예: 개행 문자, 기본 레코드 구분 기호 RS)이 있는 변수를 유지하고 비어 있지 않은 줄에 도달하면 해당 빈 줄을 인쇄하는 것입니다.

awk '/^$/{n=n RS}; /./{printf "%s",n; n=""; print}' file

print n왜 와 사이에 차이가 있는지 이해가 되지 않습니다 printf n.

print출력 레코드 구분 기호 추가( ORS, 기본값은 개행)을 인쇄할 표현식으로 설정합니다. 따라서 시도하면 추가 개행 문자를 얻게 됩니다. 다음과 같이 단일 출력 문을 사용하여 작성할 수도 있습니다.

awk '/^$/{n=n RS}; /./{printf "%s%s%s",n,$0,RS; n=""}' file

에드또는전임자

출력을 인쇄하려면(Awk와 마찬가지로) 다음 옵션 중 하나를 선택하십시오.

printf '%s\n' 'a' '' '.' '?.?+1,$d' ',p' 'Q'  | ed -s file
printf '%s\n' 'a' '' '.' '?.?+1,$d' '%p' 'q!' | ex -s file

변경 사항을 파일에 직접 적용하려면 다음 옵션 중 하나를 선택하세요.

printf '%s\n' 'a' '' '.' '?.?+1,$d' 'w' 'q'   | ed -s file
printf '%s\n' 'a' '' '.' '?.?+1,$d' 'x'       | ex -s file

무슨 일이 일어나고 있는지 이해하세요.

명령 대체

쉘은 명령 대체에서 후행 개행을 제거합니다.

printf '%s\n' "$(cat file)"

일부 쉘은 대용량 파일을 처리할 수 없으며 "인수 목록이 너무 김" 오류를 발생시킵니다.

에서 영감을 받다이 답변.

답변2

이 1단계 접근 방식은 입력이 파이프에서 나오든 파일에서 나오든 관계없이 작동하지만 빈 줄의 각 블록은 메모리에 저장되어야 합니다(입력에 수십억 개의 연속 빈 줄이 없으면 실제로 작동하지 않을 수 있음). ) 질문) ):

awk 'NF{print s $0; s=""; next} {s=s ORS}' file

이 2단계 접근 방식은 입력이 파이프인 경우에는 작동하지 않지만, 입력이 질문에서 말하는 것과 같은 파일이고 메모리를 거의 사용하지 않는 경우에는 작동하지 않습니다.

awk 'NR==FNR{if (NF) n=NR; next} FNR>n{exit} 1' file file

위의 내용에서는 공백만 포함된 줄이 "비어 있는" 줄로 간주된다고 가정합니다. 이것이 잘못된 경우 NF로 변경하십시오 /./.

답변3

awk 'length == 0 { ++n; next } { for (i = 1; i <= n; ++i) print ""; n = 0 }; 1' file

또는 댓글에 제안된 대로 줄이세요.

awk 'length == 0 { ++n; next } { while (n) { print ""; --n } }; 1'

이것은 counter 에서 빈 라인의 실행을 추적합니다 n.

빈 줄( length == 0)이 보일 때마다 카운터는 증가하지만 아무것도 인쇄되지 않습니다.

비어 있지 않은 줄이 보이면 먼저 현재 줄 앞에 적절한 수의 빈 줄을 출력하십시오. 카운터 n도 재설정됩니다.

이렇게 하면 파일 끝에서 빈 줄이 출력되는 것을 방지할 수 있습니다.


사용 표준 sed:

sed -n -e :again -e N -e '/[^\n]/!b again' -e p file

이는 버퍼에 줄바꿈 이외의 내용이 있을 때까지 버퍼에 줄을 추가하는 명시적인 루프를 도입합니다. 이 시점에서 버퍼가 출력됩니다. read 를 사용하는 동안 입력 파일이 종료되면 N버퍼의 데이터(개행만)가 출력되지 않습니다.

주석 처리된 코드(처음에는 #n을 사용하는 것과 마찬가지로 기본 출력을 끕니다 -n):

#n

# Label to branch to later.
:again

# Append next line of input to buffer
# with a delimiting newline.
N

# Branch (jump) to :again if there's
# only newlines in the buffer.
/[^\n]/!b again

# Output buffer.
p

답변4

co=`awk '!/^$/{x=NR}END{print x}' filename`
co=$(($co+1))
j="$co,$"
sed -i "${j}d" filename

테스트를 거쳐 잘 작동함

관련 정보