Five small Unix-style loop & format helpers, fully offline:
lib/each.sh
- replaces v1 `each`
- run a CMD per item: args, stdin lines, or {}-placeholder substitution
- example: tbn adt | awk '{print $2}' | each.sh 'route_test {}'
lib/each-site.sh
- replaces v1 each_site / each_site_hdr / each_site_tcl patterns
- iterates every site under $HCIROOT with HCISITE/HCISITEDIR auto-exported
- --filter REGEX limits which sites; --hdr prints a header before each
lib/len2nl.sh
- replaces v1 `len2nl`
- strict superset: handles length-prefixed (digits before MSH),
MLLP (\x0b...\x1c\x0d), and segment CRs (→ LF)
- works as stdin filter or with file arg
lib/csv-to-table.sh
- 2-column CSV → Cloverleaf .tbl format
- emits proper prologue (who, date, bidir, type, version)
- --has-header --default VALUE --bidir 0|1 --in-delim CHAR --user NAME --out PATH
lib/table-to-csv.sh
- reverse: .tbl → CSV
- --with-header --delim CHAR --include-meta
- confirmed clean round-trip: CSV → table → CSV byte-identical for the data rows
All 5 are pipeable, have --help, zero external deps beyond bash+awk+sed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
103 lines
2.2 KiB
Bash
Executable File
103 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# csv-to-table.sh — convert a 2-column CSV into Cloverleaf .tbl format.
|
|
#
|
|
# Input CSV (with or without header):
|
|
# input,output
|
|
# 12345,M
|
|
# 12346,F
|
|
# ...
|
|
#
|
|
# Output Cloverleaf .tbl:
|
|
# # Generated by csv-to-table.sh
|
|
# prologue
|
|
# who: <user>
|
|
# date: <iso8601>
|
|
# outname: output
|
|
# inname: input
|
|
# bidir: 0
|
|
# type: tbl
|
|
# version: 7.0
|
|
# end_prologue
|
|
# dflt=__non-existent__
|
|
# #
|
|
# 12345
|
|
# M
|
|
# encoded=0,0
|
|
# #
|
|
# 12346
|
|
# F
|
|
# ...
|
|
#
|
|
# Usage:
|
|
# csv-to-table.sh [FILE] [--default VALUE] [--bidir 0|1] [--has-header]
|
|
# [--in-delim CHAR] # default ','
|
|
# [--user NAME] # default $USER
|
|
# [--out PATH] # default stdout
|
|
set -o pipefail
|
|
|
|
usage() { sed -n '2,30p' "$0"; exit 0; }
|
|
|
|
INPUT=""
|
|
DEFAULT="__non-existent__"
|
|
BIDIR=0
|
|
HAS_HEADER=0
|
|
DELIM=','
|
|
USER_NAME="${USER:-larry}"
|
|
OUT_FILE=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--default) shift; DEFAULT="$1" ;;
|
|
--bidir) shift; BIDIR="$1" ;;
|
|
--has-header) HAS_HEADER=1 ;;
|
|
--in-delim) shift; DELIM="$1" ;;
|
|
--user) shift; USER_NAME="$1" ;;
|
|
--out) shift; OUT_FILE="$1" ;;
|
|
-h|--help) usage ;;
|
|
-*) echo "csv-to-table: unknown flag: $1" >&2; exit 2 ;;
|
|
*) INPUT="$1" ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
[ -z "$INPUT" ] || [ -f "$INPUT" ] || { echo "csv-to-table: no such file: $INPUT" >&2; exit 2; }
|
|
|
|
emit() {
|
|
cat <<EOF
|
|
# Generated by larry-anywhere csv-to-table.sh
|
|
prologue
|
|
who: ${USER_NAME}
|
|
date: $(date -Iseconds 2>/dev/null || date)
|
|
outname: output
|
|
inname: input
|
|
bidir: ${BIDIR}
|
|
type: tbl
|
|
version: 7.0
|
|
end_prologue
|
|
#
|
|
dflt=${DEFAULT}
|
|
#
|
|
EOF
|
|
awk -F"$DELIM" -v has_header="$HAS_HEADER" '
|
|
NR == 1 && has_header == 1 { next }
|
|
NF >= 2 {
|
|
# Trim whitespace
|
|
gsub(/^[ \t"]+|[ \t"]+$/, "", $1)
|
|
gsub(/^[ \t"]+|[ \t"]+$/, "", $2)
|
|
if ($1 == "") next
|
|
print $1
|
|
print $2
|
|
print "encoded=0,0"
|
|
print "#"
|
|
}
|
|
' "${INPUT:-/dev/stdin}"
|
|
}
|
|
|
|
if [ -n "$OUT_FILE" ]; then
|
|
mkdir -p "$(dirname "$OUT_FILE")" 2>/dev/null
|
|
emit > "$OUT_FILE"
|
|
printf 'csv-to-table: wrote %s\n' "$OUT_FILE" >&2
|
|
else
|
|
emit
|
|
fi
|