Last active
June 10, 2020 08:47
-
-
Save mvidner/3e09eaa6ada46774ea3eca9b5b2abf3a to your computer and use it in GitHub Desktop.
table_to_csv.sh: Convert a space-delimited table (where the last column may contain spaces) to CSV (comma separated value)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $ 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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/ |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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_csvoften while avoiding the Ruby startup time+space penalty, thus resorting to extreme Bash.