Piping to multiple awk commands

ludog

I'm trying to pipe the output of one command to two different awk commands. Following this post I am using tee and process substitution. However, I can't see the output for the substituted process.

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

This is supposed to show the users and memory usage for all gpu processes. The memory usage and PID are extracted from nvidia-smi, respectively, by awk '/ C / {print $6}' and awk '/ C / {print $3}' with the latter then being piped to ps -o user. The output contains only the users though.

What I would like is

<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

and what I am getting is

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

I have tried adding fflush() or stdbuf -o0 to the first awk command, as suggested here.

Paul_Pedant

More compact solution using a shell script:

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

Note, this runs three extra processes per pid.

Original solution using 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}"

The function nvidia-smi just presents some test data -- discard that. You need the AWK variable (12 lines in the multi-line constant between single-quotes) and the brief pipeline below it.

A test. I included the pid that was using the memory:

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Piping multiple commands to bash, pipe behavior question

From Dev

How to split awk output to multiple lines for piping

From Dev

Piping commands in Java

From Dev

Piping commands into the Python REPL

From Dev

Trying with piping commands into an if statement

From Dev

Piping to regular commands

From Dev

Piping grep result to awk

From Dev

Understanding Piping in AWK

From Dev

How to avoid piping awk to awk?

From Dev

Combining multiple awk commands with different delimiters

From Dev

Is there a way to write multiple awk commands on a single line?

From Dev

AWK in single line pass multiple commands

From Dev

How to merge multiple piped awk commands into a single awk command

From Dev

Piping 2 grep commands into wc

From Dev

Piping commands after a piped xargs

From Dev

Piping commands with very large output

From Dev

Does piping executes commands in parallel?

From Dev

Piping 2 grep commands into wc

From Dev

awk on multiple files and piping output of each of it's run to the wc command separately

From Dev

Piping content with multiple spaces

From Dev

Piping multiple inputs into Ghostscript

From Dev

Piping Multiple Numbers into Sed

From Dev

Piping multiple files into $variable

From Dev

Cutting a string using multiple delimiters using the awk or sed commands

From Dev

Clojure: how to execute shell commands with piping?

From Dev

What's a good example of piping commands together?

From Dev

Piping commands in plink on windows command line

From Dev

Piping fragments of a document through various commands

From Dev

Confused about piping commands from find to commandX?