`awk 'NF {p=1} p'` 파일의 시작과 끝에서 빈 줄을 제거하는 방법은 무엇입니까?

`awk 'NF {p=1} p'` 파일의 시작과 끝에서 빈 줄을 제거하는 방법은 무엇입니까?

(를 사용하여) 파일의 시작과 끝에서 빈 줄을 제거하는 방법을 찾는 동안 tac다음을 발견했습니다.

awk 'NF {p=1} p'

이것이 어떻게/왜 작동하나요?

필드가 있는 경우(행이 빈 행이 아닌 경우) NF만 이해합니다 .true

답변1

이렇게 하면 처음부터 빈 줄이 제거됩니다.하지만 끝부터가 아니야파일의.[참고: 이 답변은질문 수정언급됨 tac]

작동 방식은 다음과 같습니다.

  • NF현재 행에서 발견된 필드 수입니다. 0이면 행이 비어 있거나공백즉, 최대 공백을 포함합니다(필드 구분 기호가 기본값으로 남아 있다고 가정하고 연속 공백의 수는 구분 기호로 간주됩니다).
  • { ... }규칙 블록 외부(및 연관되지 않음)의 조건이 로 평가되면 현재 행을 인쇄합니다 true. 이 플래그는 p처음에는 초기화되지 않고 로 평가되므로 false사전에 아무 것도 인쇄되지 않습니다.
  • 비어 있지 않은 줄이 발견되면( NF0이 아니고 로 평가됨 true) 규칙 블록을 입력 {p=1}하고 p플래그를 로 설정합니다 1. 그 후에는 p규칙 블록 외부가 로 평가되고 true모든 후속 행(현재 비어 있지 않은 첫 번째 행 포함)이 인쇄됩니다.

알아채다이 플래그는 p재설정되지 않으므로 비어 있지 않은 첫 번째 줄 이후의 모든 빈 줄은 필터링 없이 인쇄됩니다. 끝에서 빈 줄도 제거하려면 2단계 접근 방식을 수행해야 합니다.

awk 'FNR==NR{if (NF) {if (!first) first=FNR; last=FNR} next}
     FNR>=first && FNR<=last' input.txt input.txt

그러면 파일이 두 번 처리됩니다(따라서 피연산자로 두 번 지정됨).

  • 각 파일 라인 카운터가 전역 라인 카운터 FNR와 동일한 첫 번째 패스에서는 비어 있지 않은 첫 번째 라인과 마지막 라인을 식별합니다.NR
  • 두 번째 패스( FNR이제 보다 작음 NR)에서는 식별된 첫 번째 줄과 비어 있지 않은 마지막 줄 사이의 줄만 인쇄합니다.

알아채다

에서 언급했듯이Stephen Chazeras의 답변, 2단계 방법은 일반 파일에만 작동합니다. 입력 내용이 성격이 다른 경우 여기에 제안된 솔루션에 대한 접근 방식을 참조하세요.

답변2

파일의 시작과 끝에서 빈 줄을 제거하려면 이 기술을 사용하십시오.

awk 'NF {p=1} p' file | # remove blank lines at the file head
  tac |                 # reverse the lines
  awk 'NF {p=1} p' |    # remove blanks from the "new head"
  tac |                 # re-reverse the file
  sponge file           # from the `moreutils` package, to overwrite the file

답변3

코드의 기능과 입력 시작 부분의 빈 줄만 제거하는 이유는 이미 설명되어 있습니다.@AdminBee의 답변예를 들어, 완전성을 기하기 위해 파일을 두 번 통과할 필요 없이 앞뒤의 빈 줄을 제거하는 대체 방법을 제안하겠습니다(이 방법은 임의 입력이 아닌 일반 파일에서만 작동합니다).

awk '
       NF {print saved $0; saved = ""; started = 1; next}
  started {saved = saved $0 ORS}' < file

이후에 볼 수 있는 비어 있지 않은 다음 줄이 나올 때까지 빈 줄의 인쇄를 지연합니다(이전에 비어 있지 않은 줄을 하나 이상 본 적이 있는 경우).

답변4

유지하려는 빈 줄에서 공백이나 탭을 분리해도 괜찮다면 시작과 끝의 빈 줄이 제거됩니다.

awk 'NF{for(;c;--c)print "";print;x=1;next} x{++c}'

비어 있지 않은 줄 사이에 나타나는 빈 줄 수를 계산하고 비어 있지 않은 각 줄 앞에 해당 개수의 빈 줄을 인쇄합니다.

관련 정보