把html文档合并,将多个HTML文档合并成一个HTML文档

'

TOKEN_CHAP_PREFIX='''

TOKEN_BODY_END=''

TOKEN_HTML_BEG=''

TOKEN_HTML_END=''

# use extended regex

GREP='egrep'

SED='sed'

# debug only

#html_path='html'

#index_page='index.html'

print_usage()

{

printf "./merge_html.sh [OPTIONS] html_path [index_page]\n"

printf "PARAMETERS:\n"

printf "\thtml_path Path to html files need to be merged.\n"

printf "\tindex_page The html file which contains toc(table of contents).\

If not provided, the html files will be merged in the order of 'ls' output.\n"

printf "OPTIONS:\n"

printf "\t--tok-toc Overide the toc(table of contents) pattern.\n"

printf "\t--tok-prefix Overide the html file tag prefix pattern. \

This will be used to address the html file name.\n"

printf "\t--tok-name Overide the html file name pattern.\n"

printf "\t-h|--help print this help message.\n"

}

# sed script1: remove address token and trailing "

cat>rm_addr_tok.sed

s/\"$//g

}

EOF

# sed script2: replace thumbnail image file name with the regular one

cat>rm_tb_pic.sed

s;${TOKEN_BODY_BEG};;g

s;${TOKEN_BODY_END};;g

s;${TOKEN_HTML_END};;g

}

EOF

# parameters

index_page_default="index.html"

html_path=

index_page=

USE_LS_RESULT=

PARSED_OPT=`getopt -o h --long tok-toc:,tok-prefix:,tok-name:,help\

-n "$0" -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

eval set -- "$PARSED_OPT"

while true;do

case "$1" in

--tok-toc)

TOKEN_TOC="$2"

echo "TOKEN_TOC: ${TOKEN_TOC}"

shift 2 ;;

--tok-prefix)

TOKEN_CHAP_PREFIX="$2"

echo "TOKEN_CHAP_PREFIX: ${TOKEN_CHAP_PREFIX}"

shift 2 ;;

--tok-name) TOKEN_CHAP_NAME="$2"

echo "TOKEN_CHAP_NAME: ${TOKEN_CHAP_NAME}"

shift 2 ;;

-h|--help) print_usage; shift ; exit 0 ;;

--) shift ; break ;; # delimter of non-option arguments

*) echo " Internal error!" ; exit 1 ;;

esac

done

# now processing non-option arguments...

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

read -p "Please specify the folder of html files need to be merged: " html_path

else

for arg do

if [[ -d $arg ]]; then

html_path=$arg

elif [[ -n $html_path && -f "$html_path/$arg" ]]; then

IS_HTML=`egrep -o "^$TOKEN_HTML_BEG|$TOKEN_HTML_END$" "$html_path/$arg"`

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

echo "Not a html file, try again." ; exit 1

fi

index_page=$arg

fi

done

fi

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

echo "No html files path specified. Exit."

exit 1

elif [[ -z "$index_page" ]]; then

echo "No index file specified, use 'ls' result instead."

USE_LS_RESULT=1

fi

if [[ -z $USE_LS_RESULT ]]; then

echo "Trying to extract TOC from index page... "

${GREP} -o "${TOKEN_TOC}" "$html_path/$index_page" > toc.tag

if [[ -s toc.tag ]]; then

${GREP} "${TOKEN_TOC}" $html_path/$index_page |${GREP} -o \

"${TOKEN_CHAP_PREFIX}${TOKEN_CHAP_NAME}" | ${SED} -f rm_addr_tok.sed > index.list

else

# fall back to 'ls' result

echo "No table of contents found in index page. Will use file order in $html_path"

# index_page must be excluded from toc ...

ls -t $html_path |${GREP} -iv "$index_page" > index.list

fi

else

# index_page must be excluded from toc ...

ls -t $html_path |${GREP} -iv "$index_page_default" > index.list

fi

echo "TOC: "

cat index.list

echo "Merging html files ... "

for i in $(< index.list)

do

# sed -f rm_tb_pic.sed -i "$html_path/$i"

sed -f rm_html_tag.sed "$html_path/$i" >> ${TARGET}

done

echo "${TOKEN_BODY_END}${TOKEN_HTML_END}" >> ${TARGET}

echo "Merged result: ${TARGET}"

使用说明

以易水老师的《Vi/Vim使用进阶》为例,将html文件下载到本地,例如html目录,然后运行

# ./merge_html.sh html index.html

搞定!其中html是待合并html文件所在目录,index.html是提供目录页的html文档。因为文档里除了index.html外第一章也包含了目录,所以就用grep把index.html从待合并文件列表中去掉了。

如果没有提供包含目录的html文件,或者文件里找不到目录信息,脚本就会使用ls命令生成待合并文件列表,并按这个顺序合并所有html文档。

由于易水老师文章的版权要求,这里就不提供转换好的html文档和pdf文档了,有需要的朋友可以下载脚本自己转一下。

对脚本的几处解释

脚本里的第二个sed命令脚本用来将《Vi/Vim使用进阶》中的小图替换成大图,这样方便直接打印。需要的话请将注释去掉

# sed -f rm_tb_pic.sed -i "$html_path/$i"

脚本使用TOKEN_TOC来匹配目录所在的行,这里有个TODO,就是如果目录是分行写的,匹配就会失败,这个问题留待以后解决。TOKEN_CHAP_PREFIX用来匹配TOC中每个章节的TAG,而TOKEN_CHAP_NAME用来匹配每个章节的标题,这几个TOKEN都可以通过脚本参数手动覆盖。

脚本参考/usr/share/doc/util-linux/examples/getopt-parse.bash脚本,使用了getopt来处理命令行参数。但getopt存在一定的可移植性问题,可以参考stackoverflow上的讨论

getopt的使用

PARSED_OPT=`getopt -o h --long tok-toc:,tok-prefix:,tok-name:,help\

-n "$0" -- "$@"`

在Linux上getopt命令是调用GNU C库的getopt函数实现的,所以支持的选项(options)规则完全一样,例如”-“指定单字符选项,后跟”:“表示该选项必须提供参数(argument),”::“表示参数可选。getopt命令本身也按照UNIX的标准处理自己的参数——需要用”- -“将非选项参数和选项隔离开来。所以需要将调用getopt命令的脚本,即merge_html.sh的命令行全部参数作为一个整体”$@“,并且是非选项参数(Non-opt arguments)传给getopt。并且为了保留命令行参数里的特殊字符需要加”“。

getopt会根据 -o和–long 指定的选项名称和类型对”$@“进行分解,得到的结果保留在PARSED_OPT变量中并将其作为”$@“供后续的while 循环和shift处理。-n ”$0“ 指定merge_html.sh为报错时getopt所使用的身份,因为getopt是给merge_html.sh打工的,所以这样处理后报错的时候显示的就是:”merge_html.sh: invalid option.” 看上去比较符合逻辑。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值