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
계산될 수 있지만 (개행 문자를 계산하기 때문에) 차이가 있을 수 있습니다.awk
wc -l
또 다른 차이점은 입력이 완전히 비어 있으면 wc -l
print 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 -n
cat
-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_lines
stderr
stdout
최대 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로 이동" 입니다 . 이를 통해 이전 출력을 계속 덮어쓸 수 있습니다.
dwc
tail -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