반복 실행 시 올바르게 작동하도록 스크립트에서 프로그램에 의해 생성된 사용량 출력의 합계를 어떻게 구현합니까?

반복 실행 시 올바르게 작동하도록 스크립트에서 프로그램에 의해 생성된 사용량 출력의 합계를 어떻게 구현합니까?

프로그램에 의해 데이터가 제한되는 파이프가 있는 스크립트가 있습니다. 20분마다 처리량 상태 보내기표준 에러, 파일로 리디렉션합니다.

command | cstream -t -512k -T 1200 -B 64m 2>>/home/user/totals.log | command

SIGUSR1 신호를 다음으로 보낼 수도 있습니다.스트림 미디어( kill -s 10 PID) 그러면 제가 했던 것처럼 간격을 설정하고 파일에 한 줄을 추가할 때와 똑같은 출력이 생성됩니다. 아이디어는 간격을 설정하고 요청 시 상태를 쿼리할 수 있다는 것입니다. 출력 형식은 다음과 같습니다. 전체 파일에 공백 문자가 하나만 있고 개행 문자로 끝납니다.

...
1931255808 B 1.8 GB 3683.6 s (1:01 h) 524289 B/s 512.00 KB/s
2560401408 B 2.4 GB 4883.6 s (1:21 h) 524289 B/s 512.00 KB/s
3189547008 B 3.0 GB 6083.6 s (1:41 h) 524289 B/s 512.00 KB/s
3818692608 B 3.6 GB 7283.6 s (2:01 h) 524289 B/s 512.00 KB/s
4447838208 B 4.1 GB 8483.6 s (2:21 h) 524289 B/s 512.00 KB/s
10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s

데이터 진행 상황을 볼 수 있지만 각 열의 합계(또는 평균)를 계산할 수는 없습니다. 이 예에는 이벤트가 2개(라인 1-5, 6)뿐이므로 스크립트를 두 번 사용합니다. 우연히 마지막 두 줄을 추가할 수 있게 되었습니다. 왜냐하면 다시 시작했고 그 순간의 스냅샷이 있기 때문입니다. 그러나 그것은 임의적입니다. 결과적으로 명령을 종료하고 다시 시작하면 마지막 줄에서 볼 수 있듯이 카운터가 재설정됩니다.

목표는 시간이 지남에 따라 시작하는 스크립트의 모든 인스턴스에 대한 상태 출력의 누적 합계를 얻는 것입니다. 저는 일반적으로 한 번에 여러 인스턴스를 시작하지 않습니다. 그래서 내 스크립트에 다음을 추가하려고 합니다("정상"은 스크립트의 한 인스턴스에만 적용됨).

  • 먼저 로그의 마지막 줄을 제외한 모든 항목을 삭제하세요.
  • 마지막으로 스크립트가 종료되면 로그에 상태를 쓰도록 합니다.
    • 첫 번째 행과 마지막 행의 각 열의 합계/평균
    • 모든 중간 줄을 제거하십시오.

점들을 연결할 수 없어서 유감입니다. 내가 원하는 것을 디자인하고 구현하는 가장 쉽고 좋은 방법은 무엇입니까? 복잡성이 이점보다 더 중요합니까? 로그 데이터가 가득 찼을 때 간단한 명령을 사용하여 로그 데이터를 조작하는 데만 집중해야 합니까?

답변1

글쎄요, 여러분이 보여주신 내용을 바탕으로 꽤 안정적으로 분류할 수 있었지만 이 데이터에는 심각한 문제가 있습니다.특이한. 당신은인간 친화적인여기의 값은 좋지 않습니다. 예를 들어 첫 번째 행과 마지막 행의 MB차이 GB- 처리는 다음과 같습니다.많은추가 작업을 수행할 필요가 없습니다. 바이트 수만 계산하면 안 될까요? 여기서 무슨 일이 일어나고 있는 걸까요 ([h]:[mm])? 왜 마지막 줄이 아닌 첫 번째 줄에 있고, 왜 유닉스 시간이 아닌가?

솔직히 말해서 이것은 기록해야 할 데이터가 전혀 아니며 그다지 유용하지도 않습니다. 물론, 읽기가 더 쉽지만 10,000줄을 읽을 수 있습니까? 내 생각에는 당신이 원하지 않는 것 같아서 질문을 하는 것입니다. 해당 출력을 변경해야 합니다. 문자를 전혀 얻지 않고 에포크 이후의 바이트 수와 초 수만 얻으면 됩니다. 이렇게 하면,많은당신에게는 더 쉽습니다.

지금 내가 말하는 건 바로 그거야했다하다:

set -- $(
sed '$bl;1H;d;:l;x;G
     s/([1-9][^)]*) //;h
     s/\n/First:&       /
     s/[^:]\(\n\)/&Last:\1      /
     w /dev/fd/2
     g' <<\DATA
1931255808 B 1.8 GB 3683.6 s (1:01 h) 524289 B/s 512.00 KB/s
2560401408 B 2.4 GB 4883.6 s (1:21 h) 524289 B/s 512.00 KB/s
3189547008 B 3.0 GB 6083.6 s (1:41 h) 524289 B/s 512.00 KB/s
3818692608 B 3.6 GB 7283.6 s (2:01 h) 524289 B/s 512.00 KB/s
4447838208 B 4.1 GB 8483.6 s (2:21 h) 524289 B/s 512.00 KB/s
10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s
DATA
)

첫 번째 sed줄은 첫 번째 줄과 마지막 줄을 가져와서 sed편집을 위해 동일한 패턴 공간에 넣는 데 필요한 모든 것입니다. 각 줄 앞에는 \n줄 문자가 옵니다. 이 명령문은 다음 작업을 모두 수행합니다.

$bl;1H;d;:l;x;G

다음 줄은 문제의 일부인 데이터의 이상한 시간 초과를 지운 다음 h이전 공간에 결과의 추가 복사본을 저장합니다.

s/([1-9][^)]*) //;h

다음 세 줄에 단어를 삽입하세요.첫 번째:그리고마지막:그런 다음 해당 줄 앞에 \newline과 <tab>문자를 추가하고 결과를 작성합니다 stderr.

 s/\n/First:&       /
 s/[^:]\(\n\)/&Last:\1      /
 w /dev/fd/2

마지막 sed줄은 이전 공간 g에서 두 번째 복사본을 가져와 h현재 패턴 공간을 덮어쓴 다음 sed최종 패턴 공간을 인쇄하고 다른 줄을 인쇄하는 기본 작업을 수행합니다 \n. 물론 현재 결과는 그다지 인상적이지 않습니다. 위 스크립트를 실행하면 다음과 같은 결과가 출력됩니다.

First:
        1931255808 B 1.8 GB 3683.6 s 524289 B/s 512.00 KB/s
Last:
        10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s

하지만 의도적으로 set결과를 쉘 배열에 넣었습니다.그리고sed어떤 이유로 이 두 줄은 의 패턴 공간에서 계속 액세스할 수 있습니다. 예를 들어, 마지막 g줄을 따라가면 sed(원한다면) 다음과 같은 패턴 공간을 사용할 수 있습니다.

\n1931255808 B 1.8 GB 3683.6 s 524289 B/s 512.00 KB/s\n10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s$ 

아니면 그대로 놔두면 이미 있는 항목에 다음을 추가하면 됩니다.

printf '%s LINE, FIELDs 1 and 2: %s and %s' \
    FIRST "$1" "$2" LAST "${11}" "${12}"

출력은 다음과 같아야 합니다.

FIRST LINE, FIELDs 1 and 2: 1931255808 and B
LAST LINE, FIELDs 1 and 2: 10829824 and B

stderr이는 이미 제공한 출력에 추가되는 것 입니다 .

관련 정보