`wc -l` 대안은 행이 수신될 때 개수를 표시합니다.

`wc -l` 대안은 행이 수신될 때 개수를 표시합니다.

wc -l입력이 파이프로 연결될 때 명령 출력의 줄 수를 계산하는 데 이것을 사용하고 있습니다 .

commad | wc -l

이것은 잘 작동하지만, command계산이 많이 진행되는 경우 속도가 느려질 수 있습니다. "지금까지 파이프된" 행 수를 표시하는 다른 방법이 있습니까?

이와 같은 것은 항목별 계산을 할 때 특히 유용합니다.

cat something | xargs -L1 heavy-per-line-computation | wc -l

이 작업을 수동으로 수행할 수 있는 한 가지 방법은 출력을 파일()로 파이프하여 command > file주기적으로 cat file | wc -l처리하는 것입니다 . 하지만 내가 원하는 것은 명령입니다(I/O 낭비를 피하기 위해 파일로 리디렉션하지 않음).

답변1

awk '{print NR}'

이 명령은 발견된 각 줄에 대해 새 번호를 인쇄합니다. 마지막 줄이 완성되면 마지막 숫자는 말한 내용과 일치합니다 wc -l. 마지막 줄이라면불완전한그런 다음 (내 Kubuntu GNU에서는 ) awk계산될 수 있지만 (개행 문자를 계산하기 때문에) 차이가 있을 수 있습니다.awkwc -l

또 다른 차이점은 입력이 완전히 비어 있으면 wc -lprint 0이고 우리는 awk아무것도 인쇄하지 않는다는 것입니다. 인쇄하려면 0다음 변형을 사용하십시오.

awk '{print NR} END {if (NR==0) print NR}'

또는 각각의 새 번호가 콘솔의 같은 행에 있는 이전 번호를 덮어쓰도록 할 수도 있습니다. 그런 다음 이:

awk '{printf "\r%s",NR} END {print "\r"NR}'

예:yes | head -n 76543 | awk '{printf "\r%s",NR} END {print "\r"NR}'

명령은 입력을 소비합니다( tee아마도 편리할 것입니다). 모니터링 목적으로 다음 사항에 관심이 있을 수 있습니다.

awk '{print NR OFS $0}'

여기서 (기본값 은 공백)는 ( 지원하는 경우) OFS거의 같습니다 .cat -ncat-n


pv -l행 수를 계산하며 파이프라인 내부에서 사용할 수 있습니다. 예:

for i in 1 2 3 4 5; do date; sleep 1; done | pv -l | wc -l

pv -lb상당히 작은 출력을 고려하십시오 .

답변2

Ruby를 사용한 솔루션입니다.

count_linesstderrstdout최대 0.5초마다 지금까지 수신된 라인 수(pass)를 인쇄하고 마지막에는 총 라인 수(pass )를 인쇄합니다 .

read -d '' make_lines <<'EOF'
  STDOUT.sync = true
  [0.2, 0.1, 0.5, 0.1, 0.6, 0.1, 0.3, 0.1, 0.3, 0.01, 0.01].each do |t|
    puts
    sleep t
  end
EOF

read -d '' count_lines <<'EOF'
  lines = 0
  t = 0
  while gets do
    lines += 1
    now = Time.now.to_f
    if now - t > 0.5
      warn lines
      t = now
    end
  end
  puts lines
EOF

ruby -e "$make_lines" | ruby -e "$count_lines"

답변3

나는 당신이 찾고 있다고 생각합니다 pv(파이프라인보기) :

seq 100000000000 | pv -l | wc -l

답변4

CR (\r)대부분의 터미널은 "열 1로 이동" 입니다 . 이를 통해 이전 출력을 계속 덮어쓸 수 있습니다.

dwctail -f이는 표준 입력( 파일 또는 출력 프로세스 대체 일 수 있음)에서 읽는 스크립트입니다 . 스크립트에 예제 테스트벤치가 있습니다.

여기에는 -l선택이 필요합니다. 기본적으로 입력 줄 번호는 터미널의 현재 줄(6자리 숫자)에 인쇄됩니다. 를 사용하면 -l수신된 마지막 줄의 처음 60자를 인쇄하고 이전 텍스트를 모두 지웁니다. EOF가 표시되면 개행 문자를 내보내어 마지막 출력 아래에 프롬프트가 나타납니다.

#! /bin/bash

#.. dwc [-l]

AWK_SHORT='
BEGIN { Fmt = "\r%6d "; }
{ printf (Fmt, NR); }
END { printf ("\n"); }
'

AWK_LONG='
BEGIN { Fmt = "\r%6d  %.60s"; Clr = sprintf ("%60s", ""); }
{ printf (Fmt, NR, $0 Clr); }
END { printf ("\n"); }
'
    if [[ "${1}" = "-l" ]]; then
        awk "${AWK_LONG}"
    else
        awk "${AWK_SHORT}"
    fi

    exit

    #.. Test method.
    man ls | head -n 40 |
         while IFS='' read X; do
             printf '%s\n' "${X}"; sleep 0.75
         done |
         tee >( ./dwc -l ) > foo.txt

관련 정보