표준 출력에 문자열 값 목록을 한 줄에 하나씩 작성하는 프로그램이 있는데, 각 값이 발생한 횟수와 함께 다양한 값 목록을 실시간으로 표시하고 싶습니다.
예를 들어, 다음 출력에서:
apple
carrot
pear
carrot
apple
이 출력을 생성하는 명령이 필요합니다(실시간으로 업데이트하는 것이 좋습니다).
apple: 2
carrot: 2
pear: 1
어떤 아이디어가 있나요?
답변1
주석에서 @Bratchley가 말한 내용을 확장하려면 프로그램 출력을 파일로 인쇄한 다음 터미널에서 then 명령을 실행하여 watch
다음과 같은 플래그를 포함하여 출력을 거의 실시간으로 볼 수 있습니다. :-n
watch -n 0.1 "cat yourprograms.log | sort | uniq -c | sort -rn"
참고: "-n" 플래그는 새로 고침 간격을 설정합니다. "시계"의 최소 시간은 0.1초(또는 1/10초)이며 더 짧을 수 없습니다.
예제 출력:
Every 0.1s: cat yourprograms.log | sort | uniq -c | sort -rn
6 things
4 mine
3 dot
1 below
포함을 사용하면 | sort -rn
보기를 더 잘 정렬할 수 있습니다. sort -rn
의 출력을 역순으로 정렬합니다.uniq -c
처음 10개에만 관심이 있는 경우 head
다음과 같은 명령을 포함할 수 있습니다.
watch -n 0.1 "cat yourprograms.log | sort | uniq -c | sort -rn | head"
답변2
여기 당신이 원하는 것을 수행하는 작은 Python 2 프로그램이 있습니다. 단어는 처음 나타나는 순서대로 나열됩니다. 즉, 각각의 새로운 단어가 목록의 맨 아래에 추가되지만 단어를 알파벳순이나 발생 횟수 순으로 정렬하는 것이 쉽습니다.
출력이 좀 더 깔끔해질 수 있습니다. 예를 들어 최대 문자열 길이를 알고 있으면 항목이 하나의 열에 정렬될 수 있습니다.
단어 개수.py
#! /usr/bin/env python
''' Real-time word counting
Written by PM 2Ring 2015.01.29
From http://unix.stackexchange.com/q/181722/88378
'''
CSI = '\x1b['
clear = CSI + '2J' + CSI + 'H'
def main():
words = []
wordcount = {}
while True:
try:
word = raw_input()
except (KeyboardInterrupt, EOFError):
print
break
if word not in wordcount:
words.append(word)
wordcount[word] = 1
else:
wordcount[word] += 1
print clear
for word in words:
print '%s: %d' % (word, wordcount[word])
if __name__ == '__main__':
main()
출력을 yourprog
이 프로그램으로 파이프하려면 다음을 수행할 수 있습니다.
yourprog | python wordcount.py
wordcount.py
현재 디렉터리에 있다고 가정합니다 .
또는 wordcount.py
실행 권한(예: chmod a+x wordcount.py
)을 부여하고 이를 명령의 PATH 목록에 있는 디렉터리(예: 실행할 때 나열된 디렉터리 echo "$PATH"
)에 넣습니다. 그럼 당신은 할 수 있습니다
yourprog | wordcount.py
어디서나 실행할 수 있습니다.
Python 3만 있고 Python 2는 없는 경우 이 프로그램을 실행하려면 몇 가지 사소한 변경이 필요합니다.
FWIW, 위의 코드를 테스트하기 위해 작성한 또 다른 Python 스크립트가 있습니다. 0.5초마다 한 줄에 한 단어씩 임의의 단어를 인쇄합니다.
임의의 단어.py
#! /usr/bin/env python
import random, time
wordlist = [
'apple',
'carrot',
'pear',
'orange',
'banana',
'cabbage',
'potato'
]
def main():
#Time delay between words, in seconds
delay = 0.5
while True:
try:
print random.choice(wordlist)
time.sleep(delay)
except KeyboardInterrupt:
print
break
if __name__ == '__main__':
main()
이를 실행하여 다음과 같이 출력을 파이핑할 수 있습니다 wordcount.py
.
python -u randwords.py | python wordcount.py
이 -u
플래그는 Python 인터프리터에게 버퍼링되지 않은 I/O를 사용하도록 지시합니다.
답변3
단순한 이상한 것. 이동 및 삭제를 위해 일부 ANSI 시퀀스를 사용하십시오.
#!/usr/bin/awk -f
BEGIN {
print "Stats:\n---------------------------------"
}
function clear() {
for (k in ar)
printf "\r\033[K\033[1A"
}
function stats() {
for (k in ar)
printf "%-10s: %d\n", k, ar[k]
}
/./{
clear()
if (!ar[$0])
ar[$0]=1
else
++ar[$0]
stats()
}
출력 생성기 예:
#!/bin/bash
declare -a fr=(
apple
carrot
pear
)
range=${#fr[@]}
while ((1)); do
((x = RANDOM % range))
printf "%s\n" "${fr[$x]}"
sleep .5
done
다음으로 실행:
$ ./fruit_script | ./awk_script
색상 확장, 커서 숨기기 등:
#!/bin/bash
quit()
{
printf "\r\033[K\033[?25h"
}
trap quit SIGINT
awk '
BEGIN {
width=3
printf "\033[?25l"
print "Stats: (Ctrl-c to quit)\n---------------------------------"
}
function clear() {
for (k in ar)
printf "\r\033[K\033[1A"
}
function stats() {
for (k in ar)
printf "\033[0;34m%-*s\033[0m: \033[1;31m%d\033[0m\n", width, k, ar[k]
}
/./{
if (length($0) + 1 > width)
width=length($0) + 1
clear()
if (!ar[$0])
ar[$0]=1
else
++ar[$0]
stats()
}
'