哈喽大家好,我是咸鱼。

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

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

具体功能:

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

主要选项:

  • -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}] '
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" '
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"
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=3
local -a lengths=() buffer="$(cat)" # 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##" while [[ $# -gt 0 ]]; do
case "$1" in
-h | --help) print_help "$1"; return 0 ;;
-[0-9]*) cols="${1:1}"; shift ;;
-s*) fs="${1:2}"; shift ;;
--csv) fs=","; shift ;;
--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 "$@"

一个能够生成 Markdown 表格的 Bash 脚本的更多相关文章

  1. 一个极简的守护进程Bash脚本

    由于最近写的Node.js程序因为一些Bug,会出现一些自动退出的问题,所以需要在它退出的时候及时发现,并重新启动 于是查阅了些资料,写了一个Bash的程序,功能十分简单,就是每隔3s判断一次处在60 ...

  2. 一个自动生成awr报告的shell脚本

    最近在学习shell编程,搞一点点小工具自动完成awr报告的收集工作,方便系统出现问题时问题排查.脚本内容如下,系统收集每天开始时间6点结束时间20点的awr报告并存储在/u01/shell_t/aw ...

  3. Linux 桌面玩家指南:06. 优雅地使用命令行及 Bash 脚本编程语言中的美学与哲学

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  4. Bash 脚本编程语言中的美学与哲学

    我承认,我再一次地当了标题党.但是不可否认,这一定是一篇精华随笔.在这一篇中,我将探讨 Bash 脚本语言中的美学与哲学. 这不是一篇 Bash 脚本编程的教程,但是却能让人更加深入地了解 Bash ...

  5. Linux应用环境实战10:Bash脚本编程语言中的美学与哲学(转)

    阅读目录 一.一切皆是字符串 二.引用和元字符 三.字符串从哪里来.到哪里去 四.再加上一点点的定义,就可以推导出整个Bash脚本语言的语法了 五.输入输出重定向 六.Bash脚本语言的美学:大道至简 ...

  6. 采用Bash脚本性能监控过程

    为一个Linux过程监控,采用Bash脚本. 采用ps命令的过程监控,使用周期加上连续监测的睡眠时间. 使用方法: psmonitor.sh -p [pid] -d [interval] -n [st ...

  7. 用 Excel 生成和管理 Markdown 表格--转载

    Markdown 作为一种轻量级的标记语言,用来进行简单的文本排版,确实方便快捷.但 Markdown 标记语言的属性,也使得其在表格处理上略显繁琐且不直观.而 Excel 几乎就是表格的代名词,借助 ...

  8. 一个很不错的bash脚本编写教程

    转自 http://blog.chinaunix.net/uid-20328094-id-95121.html 一个很不错的bash脚本编写教程,至少没接触过BASH的也能看懂! 建立一个脚本 Lin ...

  9. 在ubuntu linux 中编写一个自己的bash脚本

    在ubuntu linux 中编写一个自己的简单的bash脚本. 实现功能:终端中输入简单的命令(以pm为例(play music)),来实现音乐的播放.注:本人ununut中安装了audacious ...

  10. 在Linux环境下实现一个非常好的bash脚本框架

    为了方便我日常工作中的编译环境,免去我敲命令行所浪费的时间,我个人写了一个非常有用而又简单的脚本框架,该框架即可以完成的工程源码编译,也可以清除,拷贝等等操作,具体需要开发者自己来实现细节,我的框架思 ...

随机推荐

  1. CodeServer 不能粘贴

    CodeServer 在没有SSL证书时, 由一浏览器的限制, 默认是不能粘贴的. 在局域网中, 如果不考虑安全性的话, 可以考虑直接把加密关掉, 就能复制粘贴了. 配置文件如下: cert: Tru ...

  2. .NET 个人博客-首页排版优化

    个人博客-首页排版优化 优化计划 置顶3个且可滚动或切换 推荐改为4个,然后新增历史文章,将推荐的加载更多放入历史文章,按文章发布时间降序排列. 标签功能,可以为文章贴上标签 推荐点赞功能 本篇文章优 ...

  3. 面试官:Java线程可以无限创建吗?

    哈喽,大家好,我是世杰. 本次给大家介绍一下操作系统线程和Java的线程以及二者的关联 1. 面试连环call Java线程可以无限创建吗? Java线程和操作系统线程有什么关联? 操作系统为什么要区 ...

  4. 前端:如何让background背景图片进行CSS自适应

    在设置login背景时,找到了一张这样的图片: 但是设置成login背景时,如果没有做一些css适应设置,图片就变样了,变成了这样: 严重变形了,这就造成了一种理想与现实的差距. 若想解决这个自适应问 ...

  5. MakeSense标注指南

    1.网址 https://www.makesense.ai/ 2.操作流程 2.1 导入 点击get started 点击drop images,上传图片 选择obeject detection 新建 ...

  6. 权威技术社区InfoQ列网易数帆为年度最有价值技术团队,技术实力获广泛认可

    近日,权威技术社区InfoQ公布数字化转型技术服务商网易数帆为2020年最有价值技术团队,并被授予"最佳技术社区驱动力奖",认可网易数帆在技术领域的突出成就和实力.     Inf ...

  7. 图扑低代码数字孪生 Web SCADA 智慧钢厂

    2024 年 4 月,中国钢铁工业协会发布了<钢铁行业数字化转型评估报告(2023年)>(以下简称<报告>).<报告>指出,绝大部分钢铁企业建立了数字化转型相关管理 ...

  8. SQL Server 验证某栏位是否存在某字符串(CHARINDEX)

    SELECT * FROM LiuJun_PKqitchqi WHERE CHARINDEX('230527Z3258',qr_code) > 0

  9. Java 中的一些知识点

    Java 中的一些知识点 Java 中的知识点 与C++相关 toString方法 super 与C++相关[了解的不是很多] 在Java程序中:一个方法以 ; 结尾,并且修饰符列表中有 native ...

  10. 题解:P10329 [UESTCPC 2024] Add

    Add 题意 将序列进行一系列的操作,输出对 \(a_{1}\) 的期望值. 题目中操作说的比较明了,再次就不特殊声明了. 思路 据题意所知,每一个 \(n\) 应该对应了一个固定的答案. 于是我就想 ...