Skip to content

Instantly share code, notes, and snippets.

@mvidner
Last active Jun 10, 2020
Embed
What would you like to do?
table_to_csv.sh: Convert a space-delimited table (where the last column may contain spaces) to CSV (comma separated value)
$ ps -f | tee /dev/stderr | ./table_to_csv > ps.csv
UID PID PPID C STIME TTY TIME CMD
martin 12310 3022 0 09:36 pts/13 00:00:00 /bin/bash
martin 13255 12310 0 10:18 pts/13 00:00:00 ps -f
martin 13256 12310 0 10:18 pts/13 00:00:00 tee /dev/stderr
martin 13257 12310 0 10:18 pts/13 00:00:00 /bin/bash ./table_to_csv
UID PID PPID C STIME TTY TIME CMD
martin 12310 3022 0 09:36 pts/13 00:00:00 /bin/bash
martin 13255 12310 0 10:18 pts/13 00:00:00 ps -f
martin 13256 12310 0 10:18 pts/13 00:00:00 tee /dev/stderr
martin 13257 12310 0 10:18 pts/13 00:00:00 /bin/bash ./table_to_csv
#!/bin/bash
# Convert a space-delimited table (where the last column may contain spaces)
# to CSV (comma separated value).
# Usage: ps -eF | ./table_to_csv
# Example:
# ps -f | tee '/tmp/the script and the CSV handles non-word characters: \ " , *' | ./table_to_csv
# "UID","PID","PPID","C","STIME","TTY","TIME","CMD"
# "martin","12310","3022","0","09:36","pts/13","00:00:00","/bin/bash"
# "martin","13320","12310","0","10:24","pts/13","00:00:00","ps -f"
# "martin","13321","12310","0","10:24","pts/13","00:00:00","tee /tmp/the script and the CSV handles non-word characters: \ "" , *"
# "martin","13322","12310","0","10:24","pts/13","00:00:00","/bin/bash ./table_to_csv"
Q='"' # to escape " as ""
while read -r LINE; do
read -r -a FIELDS <<< "$LINE" # split words into array
# Detect the number of columns, based on the fact that
# there are at least 2 columns and
# the first line does not contain spaces in the last column
if (( LASTCOL == 0 )); then
LASTCOL=$((${#FIELDS[@]} - 1))
fi
for I in "${!FIELDS[@]}"; do # indices of FIELDS
if (( I == LASTCOL )); then break; fi
printf '"%s",' "${FIELDS[$I]/$Q/$Q$Q}"
done
LAST="${FIELDS[*]:$LASTCOL}" # array slice
printf '"%s"\n' "${LAST/$Q/$Q$Q}"
done
# For sanity in shell scripting, shellcheck table_to_csv
# See https://www.shellcheck.net/
@mvidner

This comment has been minimized.

Copy link
Owner Author

@mvidner mvidner commented Jun 10, 2020

Why not implement this in a scripting language with a more sane syntax and better string+CSV libraries, say Ruby?

The intent here is to call ps ... | table_to_csv often while avoiding the Ruby startup time+space penalty, thus resorting to extreme Bash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment