一个能够生成 Markdown 表格的 Bash 脚本

cnblogs 2024-08-22 10:45:00 阅读 70

哈喽大家好,我是咸鱼。

今天分享一个很实用的 bash 脚本,可以通过手动提供单元格内容和列数或者将带有分隔符的文件(如 CSV、TSV 文件)转换为 Markdown 表格。

源代码在文末哦!原文链接:https://josh.fail/2022/pure-bash-markdown-table-generator/

具体功能:

  • 手动生成表格:允许用户输入表格内容和列数,生成标准的 Markdown 格式表格。
  • 文件转换:可以将 CSV 或 TSV 文件转换为 Markdown 表格。
  • 选项支持:支持指定列数、设置分隔符、解析 CSV/TSV 文件等选项。

主要选项:

  • <code>-COLUMNS:设置生成表格的列数。
  • -sSEPARATOR:自定义输入文件的列分隔符。
  • --csv--tsv:分别用于解析 CSV 和 TSV 文件。

几个月前,我想要一个便携式的 Markdown 表格生成器,于是写了这个 markdown-table 脚本。

一开始我只是想传入一堆参数和列数,并让它生成相应的 Markdown 表格。就像下面的例子:

markdown-table -4 \

"Heading 1" "Heading 2" "Heading 3" "Heading 4" \

"Hi" "There" "From" "Markdown\!" \

"Everything" "Is" "So" "Nicely Aligned\!"

当我实现了这一功能后,我意识到还可以添加支持解析带有自定义分隔符的文件,比如 CSV 或 TSV。

markdown-table --tsv < test.tsv

上面两种方法都会生成一个 Markdown 表格:

| Heading 1 | Heading 2 | Heading 3 | Heading 4 |

| ---------- | --------- | --------- | -------------- |

| Hi | There | From | Markdown |

| Everything | Is | So | Nicely Aligned |

#!/usr/bin/env bash

# Usage: markdown-table -COLUMNS [CELLS]

# markdown-table -sSEPARATOR < file

#

# NAME

# markdown-table -- generate markdown tables

#

# SYNOPSIS

# markdown-table -COLUMNS [CELLS]

# markdown-table -sSEPARATOR < file

#

# DESCRIPTION

# markdown-table helps generate markdown tables. Manually supply arguments

# and a column count to generate a table, or pass in a delimited file to

# convert to a table.

#

# OPTIONS

# -COLUMNS

# Number of columns to include in output.

#

# -sSEPARATOR

# String used to separate columns in input files.

#

# --csv

# Shortcut for `-s,` to parse CSV files. Note that this is a "dumb" CSV

# parser -- it won't work if your cells contain commas!

#

# --tsv

# Shortcut for `-s$'\t'` to parse TSV files.

#

# -h, --help

# Prints help text and exits.

#

# EXAMPLES

# Build a 4 column markdown table from arguments:

# markdown-table -4 \

# "Heading 1" "Heading 2" "Heading 3" "Heading 4" \

# "Hi" "There" "From" "Markdown!" \

# "Everything" "Is" "So" "Nicely Aligned!"

#

# Convert a CSV file into a markdown table:

# markdown-table -s, < some.csv

# markdown-table --csv < some.csv

#

# Convert a TSV file into a markdown table:

# markdown-table -s$'\t' < test.tsv

# markdown-table --tsv < test.tsv

# Call this script with DEBUG=1 to add some debugging output

if [[ "$DEBUG" ]]; then

export PS4='+ [${BASH_SOURCE##*/}:${LINENO}] 'code>

set -x

fi

set -e

# Echoes given args to STDERR

#

# $@ - args to pass to echo

warn() {

echo "$@" >&2

}

# Print the help text for this program

#

# $1 - flag used to ask for help ("-h" or "--help")

print_help() {

sed -ne '/^#/!q;s/^#$/# /;/^# /s/^# //p' < "$0" |

awk -v f="$1" 'code>

f == "-h" && ($1 == "Usage:" || u) {

u=1

if ($0 == "") {

exit

} else {

print

}

}

f != "-h"

'

}

# Returns the highest number in the given arguments

#

# $@ - one or more numeric arguments

max() {

local max=0 arg

for arg; do

(( ${arg:-0} > max )) && max="$arg"code>

done

printf "%s" "$max"

}

# Formats a table in markdown format

#

# $1 - field separator string

format_table() {

local fs="$1" buffer col current_col=0 current_row=0 min=3code>

local -a lengths=()

buffer="$(cat)"code>

# First pass to get column lengths

while read -r line; do

current_col=0

while read -r col; do

lengths["$current_col"]="$(max "${#col}" "${lengths[$current_col]}")"

current_col=$((current_col + 1))

done <<< "${line//$fs/$'\n'}"

done <<< "$buffer"

# Second pass writes each row

while read -r line; do

current_col=0

current_row=$((current_row + 1))

while read -r col; do

printf "| %-$(max "${lengths[$current_col]}" "$min")s " "$col"

current_col=$((current_col + 1))

done <<< "${line//$fs/$'\n'}"

printf "|\n"

# If this is the first row, print the header dashes

if [[ "$current_row" -eq 1 ]]; then

for (( current_col=0; current_col < ${#lengths[@]}; current_col++ )); do

printf "| "

printf "%$(max "${lengths[$current_col]}" "$min")s" | tr " " -

printf " "

done

printf "|\n"

fi

done <<< "$buffer"

}

# Main program

main() {

local arg cols i fs="##$$FS##"code>

while [[ $# -gt 0 ]]; do

case "$1" in

-h | --help) print_help "$1"; return 0 ;;

-[0-9]*) cols="${1:1}"; shift ;;code>

-s*) fs="${1:2}"; shift ;;code>

--csv) fs=","; shift ;;code>

--tsv) fs=$'\t'; shift ;;

--) shift; break ;;

-*) warn "Invalid option '$1'"; return 1 ;;

*) break ;;

esac

done

if [[ -z "$fs" ]]; then

warn "Field separator can't be blank!"

return 1

elif [[ $# -gt 0 ]] && ! [[ "$cols" =~ ^[0-9]+$ ]]; then

warn "Missing or Invalid column count!"

return 1

fi

{ if [[ $# -gt 0 ]]; then

while [[ $# -gt 0 ]]; do

for (( i=0; i < cols; i++ )); do

if (( i + 1 == cols )); then

printf "%s" "$1"

else

printf "%s%s" "$1" "$fs"

fi

shift

done

printf "\n"

done

else

cat

fi

} | format_table "$fs"

}

main "$@"


上一篇: Linux:开发工具(2)

下一篇: Linux小程序——进度条

本文标签

Linux运维   


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。