csvjson path/to/infile.csv \
| jq -c ".[]" \
| while read LINE; do
UNAME="$(echo "$LINE" | jq -r ".uname")";
CNAME="$(echo "$LINE" | jq -r ".cname")";
if id -u "$UNAME" &> /dev/null; then
# Find processes with this command name belonging to this user
comm -12 <(ps -C "$CNAME" -o "pid=" | sort) <(ps -U "$UNAME" -o "pid=" | sort) | \
while read PID; do
# rss=Resident Set Size, i.e. the amount of memory this process is currently
# using, not including swap. You might want vsize instead, depending on your needs.
RSS="$(ps -o "rss=" "$PID")";
STARTISODATE="$(date --date="$(ps -o "lstart=" "$PID")" --iso-8601="seconds")";
# If you actually plan to use this you need to make sure pid isn't anything important
kill "$PID";
jq -n -c \
--argjson "pid" "$PID" \
--argjson "rss" "$RSS" \
--arg "start" "$STARTISODATE" \
--arg "command" "$CNAME" \
--arg "username" "$UNAME" \
'{"pid":$pid,"memory_kb":$rss,"start":$start,"command":$command,"username":$username}';
done
else
# Print an error to stdout if the user does not exist
echo "warning: user $UNAME does not exist" >&2
fi
done \
| jq -s 'sort_by(.memory_kb)' \ # sort_by(-.memory_kb) if you want it in descending order
| in2csv --format=json \
> path/to/outfile.csv
I'm guessing you meant "parse the CSV correctly using only bash", and I agree that's difficult, which is why you should not do that. Instead, you should use a tool that has been specifically designed to do that one task, and do it well (in this case, that task is "convert a csv into a format that's easier to work with, namely json"). This is the unix way.How extensible is PowerShell? With bash, you can write a new command that takes text input in a certain format and produces text output in a certain format, in whatever language you want, and plug it in in the appropriate place in the pipeline. Is the same true of PowerShell?