여러 awk 명령으로 파이프

여러 awk 명령으로 파이프

한 명령의 출력을 두 개의 다른 명령으로 파이프하려고 합니다 awk. 다음과 같은이 게시물tee교체해서 사용하고 있습니다 . 그러나 교체 프로세스의 출력을 볼 수 없습니다.

nvidia-smi | tee >(awk '/ C / {print $6}') | awk '/ C / {print $3}' | xargs -r ps -o user

여기에는 모든 GPU 프로세스에 대한 사용자 및 메모리 사용량이 표시됩니다. 메모리 사용량과 PID는 및 각각에 의해 추출되고 nvidia-smi후자는 에 파이프됩니다. 그러나 출력에는 사용자만 포함됩니다.awk '/ C / {print $6}'awk '/ C / {print $3}'ps -o user

내가 원하는 건

<memory-of-process1> <name-of-user-running-process1>
<memory-of-process2> <name-of-user-running-process2>
<memory-of-process3> <name-of-user-running-process3> 
etc

내가 얻는 것은

<name-of-user-running-process1>
<name-of-user-running-process2>
<name-of-user-running-process3>
etc

제안된 대로 첫 번째 awk 명령에 fflush()또는 추가를 시도했습니다.stdbuf -o0여기.

답변1

쉘 스크립트를 사용하는 보다 컴팩트한 솔루션:

nvidia-smi | grep ' C ' | while read _ _ pid _ _ mem; do
    user="$( ps -o user "${pid}" | tail -n +2 )"
    printf '%8s  %6d  %s\n' "${mem}" "${pid}" "${user}"
done

이는 pid당 3개의 추가 프로세스를 실행한다는 점에 유의하세요.

원래 솔루션은 다음을 사용합니다 awk.

#! /bin/bash

function nvidia-smi { cat <<'[][]'
A C 937 D E 1.7MB
A C 1232 D E 0.25MB
A E 6112 D E 13MB
A C 2008 D E 437KB
A C 2024 D E 314157
[][]
}

AWK='
/ C / { Pid[NR] = $3; xPid[$3] = NR; Mem[NR] = $6; }
END {
    for (j in Pid) pp = pp "," Pid[j];
    cmd = "ps 2>&1 -o pid,user -p " substr (pp, 2);
    while (cmd | getline) 
        if ($1 in xPid) User[xPid[$1]] = $2;
    close (cmd);
    fmt = "%8s  %6d  %s\n";
    for (j = 1; j <= NR; ++j) 
        if (j in Mem)
            printf (fmt, Mem[j], Pid[j], User[j]);
}
'
    nvidia-smi | awk "${AWK}"

nvidia-smi 함수는 일부 테스트 데이터를 제공할 뿐입니다. 이를 폐기하세요. AWK 변수(작은따옴표 사이의 여러 줄 상수의 12번째 줄)와 그 아래의 짧은 파이프가 필요합니다.

시험. 사용 중인 메모리의 PID를 포함했습니다.

paul $ ./nVid
   1.7MB     937  syslog
  0.25MB    1232  root
   437KB    2008  postfix
  314157    2024  paul

관련 정보