파일 끝에서 빈 줄 수를 센다


11

파일 끝에 빈 줄이있는 파일이 있습니다. grep스크립트에서 파일 이름이 변수로 전달되는 파일 끝의 빈 줄 수를 계산하는 데 사용할 수 있습니까 ?


연속적인 빈 줄 의 수를 세려면 ?
RomanPerekhrest

2
@RomanPerekhrest 내가 그렇게 말하고 싶지 않다면 그렇지 않으면 "파일의 끝"에 있지 않을 것입니까?
Sparhawk

'grep -cv -P'\ S 'filename'은 파일의 총 빈 줄 수를 계산합니다. 결국 숫자는 단지 내 뇌에 부담을줍니다!
MichaelJohn

OP는 grep@MichaelJohn 에게 내 책에서 순결 을 얻었습니다.
bu5hman

2
@ bu5hman 그러나 (그가 인정하는 것처럼) 질문에 대답하지 않습니다. 당신도 마찬가지입니다.
Sparhawk

답변:


11

빈 줄이 끝에 있는 경우

grep  -c '^$' myFile

또는:

grep -cx '' myFile

dammit
bu5hman

grep -cv . myFile코드 골퍼를위한 다른 방법입니다. 그러나 grep파일의 아무 곳에 나 빈 줄이 있으면 해결책을 찾았습니다 .
Philippos

2
@Philippos grep -cv .는 유효한 문자를 형성하지 않는 바이트 만 포함하는 행도 계산합니다.
Stéphane Chazelas

11

재미를 위해서, 짜증나는 것 sed:

#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l

설명:

  • /./임의의 문자로 행을 처리하므로 /./!비어 있지 않은 행을 처리합니다. 이를 위해 H명령은 보류 공간에 추가합니다. 따라서 각 빈 줄에 대해 보류 공간에 한 줄을 추가 한 경우 빈 줄 수보다 항상 한 줄이 더 있습니다. 나중에 처리하겠습니다.
  • //h빈 패턴은 문자 인 마지막 정규식과 일치하므로 비어 있지 않은 행은 주소가 지정되고 수집 된 행을 1로 "재설정"하는 명령에 의해 보류 공간으로 이동 됩니다 h. 다음 빈 행이 추가되면, 예상대로 두 개가 다시있을 것입니다.
  • $!d마지막 행을 제외한 모든 행에 대해 출력없이 스크립트를 중지하므로 추가 명령은 마지막 행 이후에만 실행됩니다. 보류 공간에서 수집 한 빈 줄은 모두 파일 끝에 있습니다. 좋은.
  • //d: d비어 있지 않은 행에 대해서만 명령이 다시 실행됩니다. 따라서 마지막 줄이 비어 있지 sed않으면 출력없이 종료됩니다. 제로 라인. 좋은.
  • x 교환은 공간과 패턴 공간을 보유하므로 수집 된 라인은 이제 처리 될 패턴 공간에 있습니다.
  • 그러나 한 줄이 너무 많다는 것을 기억하므로을 사용하여 줄 바꿈 하나를 제거하여 줄을 줄입니다 s/\n//.
  • oil! 줄 수는 끝에있는 빈 줄 수와 일치합니다 (첫 번째 줄은 비어 있지 않지만 누가 신경 써야할지에주의하십시오) wc -l.

8

더 많은 GNU tac/ tail -r옵션 :

tac file | awk 'NF{exit};END{print NR?NR-1:0}'

또는:

tac file | sed -n '/[^[:blank:]]/q;p' | wc -l

다음의 출력에 유의하십시오.

printf 'x\n '

즉, 마지막 전체 줄 다음에 여분의 공백이있는 경우 (일부는 여분의 빈 줄로 간주 될 수 있지만 POSIX 텍스트 정의에 의해 유효한 텍스트가 아님) 0을 제공합니다.

POSIXly :

awk 'NF{n=NR};END{print NR-n}' < file

그러나 그것은 파일을 완전히 읽는 것을 의미합니다 ( tail -r/ tac는 찾기 가능한 파일의 끝에서 파일을 뒤로 읽습니다). 그것은 1의 출력을 제공합니다 printf 'x\n '.


6

실제로 grep솔루션을 요구할 때 GNU에만 의존하는 이것을 추가합니다 grep(좋아요, 쉘 구문과 echo...을 사용합니다).

#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))

내가 여기서 뭘하고있는 거지? $(grep -c ".*" "$1")파일의 모든 줄을 세고, 마지막 빈 줄없이 파일을 뺍니다.

어떻게 구할 수 있습니까? $(grep -B42 . "$1"비어 있지 않은 줄과 42 줄을 모두 앞에 그리십시오. 비어 있지 않은 줄 앞에 42 줄을 넘지 않는 한 마지막 비어 있지 않은 줄까지 모든 것을 인쇄합니다. 이 한계를 피하기 위해 옵션 $(grep -cv . "$1")의 매개 변수로 사용합니다 -B. 이는 빈 줄의 총 수이므로 항상 충분히 큽니다. 이 방법으로 후행 빈 줄을 제거하고 줄 |grep -c ".*"을 계산하는 데 사용할 수 있습니다 .

훌륭하지 않습니까? (-;


+1 끔찍한 코드 임에도 불구하고 기술적으로 요청 된대로 질문에 대답하며 표시 할 수 없습니다 ;-)
roaima

그렙 마이스터. 우리는 합당하지 않습니다.
bu5hman

퍼버 시티의 경우 +1 다른 (아마도 더 빠른?) 옵션은 tac | grep공백이 아닌 첫 번째 공백이 아닌 -m -A 42다음에 빼는 것입니다. 어느 것이 더 효율적인지 잘 모르겠지만 wc -l | cut -d' ' -f1빈 줄을 잡는 대신에?
Sparhawk

예, 물론, 당신과 함께 많은 것들을 할 수있는 tac, wc그리고 cut있지만, 나는 여기에 자신을 제한하기 위해 노력했다 grep. 당신은 그것을 불변이라고 부를 수 있습니다. (-;
Philippos

5

또 다른 awk해결책. 이 변형 k은 빈 줄이 없을 때마다 카운터를 다시 설정합니다 . 그런 다음 모든 줄이 카운터를 증가시킵니다. (따라서 첫 번째 공백이 아닌 길이 줄 뒤에 k==0.) 끝에서 계산 한 줄 수를 출력합니다.

데이터 파일 준비

cat <<'X' >input.txt
aaa

bbb
ccc



X

샘플에서 마지막 빈 줄을 세십시오.

awk 'NF {k=-1}; {k++}; END {print k+0}' input.txt
3

이 정의에서 빈 줄은 공백이나 다른 빈 문자를 포함 할 수 있습니다. 여전히 비어 있습니다. 빈 줄 대신 빈 줄을 세려면으로 변경 NF하십시오 $0 != "".


$0 > ""? 그것은 많은 구현에서 사용 strcoll()하는 것보다 덜 효율적인 것을 $0 != ""사용합니다 memcmp()(POSIX는 그것을 사용하도록 요구했습니다 strcoll()).
Stéphane Chazelas

@ StéphaneChazelas 나는 그것과 $0 > ""다를 수도 있다고 생각하지 않았습니다 $0 != "". awk어쨌든 "느린"연산자 로 취급하는 경향이 있습니다 (내가 입력으로 큰 데이터 세트를 가지고 있고 처리가 시간이 중요하다는 것을 알고 있다면 처리해야 할 양을 줄이기 위해 내가 할 수있는 일을 보게 될 것입니다 awk-I grep | awk그런 상황에서 구조를 사용 했습니다). 그러나 내가 생각하는 것을 간략하게 살펴보면 POSIX 정의가strcoll()또는에 대한 참조를 볼 수 없습니다 memcmp(). 내가 무엇을 놓치고 있습니까?
roaima

strcoll()== 문자열은 로케일 별 조합 순서를 사용하여 비교해야합니다 . 이전 판 과 비교하십시오 . 나는 그것을 키우는 사람이었습니다. 참조 austingroupbugs.net/view.php?id=963
스테판 Chazelas가에게

@ StéphaneChazelas a <= b && a >= b와 반드시 동일하지 않은 구현 a == b. 아야!
roaima

즉 GNU의 사건 awk이나 bash(그에 [[ a < b ]]대한 예를 들어 GNU 시스템은 en_US.UTF-8 로켈에서 사업자) 예를 들어 (대한 bash의 없음, <, >, =true를 반환). 논란의 여지는 더 떠들썩한 파티 / AWK보다 그 로케일의 정의의 버그입니다
스테판 Chazelas가

2

파일 끝에서 연속적인 빈 줄 수를 계산합니다.

고체 awk+ tac용액 :

샘플 input.txt:

$ cat input.txt
aaa

bbb
ccc



$  # command line 

행동 :

awk '!NF{ if (NR==++c) { cnt++ } else exit }END{ print int(cnt) }' <(tac input.txt)
  • !NF-현재 행이 비어 있는지 확인합니다 (필드가 없음).
  • NR==++c-빈 줄의 연속 순서를 보장합니다. ( NR-레코드 번호 ++c-균등하게 증가 된 보조 카운터)
  • cnt++- 줄의 카운터

출력 :

3

1

IIUC, 다음 스크립트 count-blank-at-the-end.sh가 작업을 수행합니다.

#!/usr/bin/env sh

count=$(tail -n +"$(grep . "$1" -n | tail -n 1 | cut -d: -f1)" "$1" | wc -l)
num_of_blank_lines=$((count - 1))

printf "%s\n" "$num_of_blank_lines"

사용법 예 :

$ ./count-blank-at-the-end.sh FILE
4

나는 그것을에서 테스트 GNU bash, Android mksh및의 ksh.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.