行者无疆 始于足下 - 行走,思考,在路上
万方学位论文pdf合并脚本v0.1
古人云:天下文章一大抄。整个三月,浙江大学CS开题报告热火朝天,其中各种纠结与不解、各种困惑与混乱、各种word/tex模版纷争,不再详述。23号提交论文,但时至此刻,我刚刚Google Translate了一片水文搞定了外文翻译,修改了学院bug百出的latex模版,搞定了开题报告的格式,至于剩下的3500字,尚无着落,痛苦不堪,心慌也。
废话少说,今天晚上去万方数据库校内镜像下载学位论文,岂知万方这个财主极其抠门猥琐,不但很多有价值的学术论文无法下载,可以下载的论文也是一个zip压缩包,然后里面几十到上百个pdf不等……看一篇完整的学位论文要打开几十个pdf,莫说是我,就是我的x201i,也该累死了……
一个典型的万方学位论文zip压缩包目录结构如下:
lox >>> tree IPTV机顶盒GUI子系统的研究与实现 IPTV机顶盒GUI子系统的研究与实现 ├── default.htm ├── Images │ ├── ball.gif lox >>> tree -L 3 -p -N | grep '\[d' └── [drwxrwxr-x] wanfang ├── [drwxrwxr-x] IPTV机顶盒GUI子系统的研究与实现 │ ├── [drwxrwxr-x] Images │ └── [drwxrwxr-x] Paper ├── [drwxrwxr-x] Tools设计与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 基于QtEmbedded的图形用户界面移植 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 基于嵌入式Linux智能手机GUI平台的研究与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 基于消息通信机制嵌入式GUI的研究与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 嵌入式Linux图形用户界面的研究与开发 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 嵌入式uGUI的研究与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 嵌入式系统轻量化GUI框架的设计与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper └── [drwxrwxr-x] 面向数字家电产品的GUI框架的设计与实现 ├── [drwxrwxr-x] Images ├── [drwxrwxr-x] Paper │ ├── bg.gif │ ├── folder.gif │ ├── H.gif │ ├── I.gif │ ├── L.gif │ ├── nfolder.gif │ ├── ofolder.gif lox >>> tree IPTV机顶盒GUI子系统的研究与实现 IPTV机顶盒GUI子系统的研究与实现 ├── default.htm ├── Images │ ├── ball.gif │ ├── bg.gif │ ├── folder.gif │ ├── H.gif │ ├── I.gif │ ├── L.gif │ ├── nfolder.gif │ ├── ofolder.gif │ └── T.gif └── Paper └── pdf ├── d0447950001.pdf ├── d0447950002.pdf ├── d0447950003.pdf ├── d0447950004.pdf ├── d0447950005.pdf ├── d0447950006.pdf ├── d0447950007.pdf ├── d0447950008.pdf ├── d0447950009.pdf ├── d044795wz.pdf ├── d044795zye.pdf ├── fm.htm ├── index.htm ├── iptv.pdf ├── left.htm ├── ml.htm └── single_merged_pdf.pdf 3 directories, 28 files
所有的pdf文档在./Paper/pdf目录下,并且必有一个xxxxwz.pdf和一个xxxxzye.pdf文件,剩下的pdf文件基本上内容顺序和编号顺序一致,但是不排除有页码重叠的状况。
想到的办法就是找CLI工具,将这些pdf合并成一份完整的论文。Archlinux下:pacman -Ss pdf,结合Google,得到几个相关的pdf工具:
- pdfedit
- ghostscript
- pdftk
- poppler
pdfedit是图形化的pdf edit(编辑)工具,显然不符合CLI自动化处理的要求。而且看界面是基于QT3.x的,编辑功能应该是很强大的。具体可以看pdfedit的Screenshots。不过这与本文无关了。
ghostscript is an interpreter for the PostScript language。linuxtoy给出了一种合并pdf方法,我尝试了一下,但是万方本身的pdf是加密的,直接转换会出现莫名其妙的错误,所以这种方法最终失败。
pdftk是一个十分强大的pdf工具,按照官方的说法,pdftk可以用来:
- Merge PDF Documents
- Split PDF Pages into a New Document
- Rotate PDF Pages or Documents
- Decrypt Input as Necessary (Password Required)
- Encrypt Output as Desired
- Fill PDF Forms with FDF Data or XFDF Data and/or Flatten Forms
- Apply a Background Watermark or a Foreground Stamp
- Report on PDF Metrics such as Metadata, Bookmarks, and Page Labels
- Update PDF Metadata
- Attach Files to PDF Pages or the PDF Document
- Unpack PDF Attachments
- Burst a PDF Document into Single Pages
- Uncompress and Re-Compress Page Streams
- Repair Corrupted PDF (Where Possible)
可以用pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf的方式来合并pdf,但是由于万方pdf的特殊加密,用pdftk合并时,会出现"OWNER PASSWORD REQUIRED"的失败提示。所以成功合并pdf的最关键问题就是去掉万方pdf加密。
幸运的是,我在townx找到了解决方法,感谢万能的Google。剩下的任务,就是Shell Script的天地了。
至于Shell Script,已经好久没有摆弄,很多写法已经生疏,好在半年前在华数淘宝写的脚本还在,打开浏览了下,照葫芦画瓢,倒也没有遇到太大困难。完整的脚本如下:
#!/usr/bin/env bash ################################################################################ # Purpose: Merge pdf file downloaded from Wanfang dissertation database # (http://g.wanfangdata.com.cn/) # Author: Xiao Hanyu(xiaohanyu1988@gmail.com) # Depends: # pdftk: merge multiple pdf files, pdftk is also a useful pdf # manipulation tools # ps2pdf/pdftops: pdf --> ps then ps --> pdf to remove encryption ################################################################################ function usage { cat << EOF `basename $0`: A utility to merge encryted pdf files into one single pdf Usage: `basename $0` [Options] Example: `basename $0` -f "file1.pdf file2.pdf" -o merged.pdf `basename $0` -d input_pdf_dir -o merged.pdf `basename $0` -d input_pdf_dir Options: -f: set the input pdf file list -d: set the input pdf directory -o: set the output pdf filename -h: show this help EOF } function merge_pdfs { echo "######## Convert begin!! ########" for pdf in $pdf_list do ## do not use pdf_name = `basename $pdf .pdf` ## since basename will remove the directory prefix of $pdf pdf_name=`echo $pdf | sed -e "s/\.pdf//"` ## add some animation ^_^ echo -n "$pdf_name.pdf ---->> $pdf_name.ps " pdftops $pdf_name.pdf $pdf_name.ps echo "---->> $pdf_name.pdf" ps2pdf $pdf_name.ps $pdf_name.pdf rm -rf $pdf_name.ps done echo "######## Convert end!! ########" echo "######## Merge begin!! ########" pdftk $pdf_list cat output $pdf_merge echo "######## Merge success, open $pdf_merge to see the result. Bye!! ########" } while getopts "d:f:o:h" arg do case $arg in d) pdf_dir=$OPTARG pdf_list=`ls $pdf_dir/*pdf` ;; f) pdf_list=$OPTARG ;; o) pdf_merge=$OPTARG ;; h) usage exit 0 ;; ?) echo "!!Wrong command options" usage exit 1 ;; esac done # if pdf_dir is not set yet, then it's set to default(that is, current directory) pdf_dir=${pdf_dir:-"."} # set default output pdf filename, plus $pdf_dir prefix pdf_merge="${pdf_dir}/${pdf_merge:-"single_merged_pdf.pdf"}" merge_pdfs
脚本结构还是很简单的:
- 参数解析采用bash内置的getopts,暂时只支持短选项;
- 有一个帮助说明函数function usage{};
- 关键函数是function merge_pdfs{},尤其需要注意目录名和文件名的处理;
调用方法如function usage{}里面所示:
- ./wanfang_pdf_merge.sh -d pdf_dir
- ./wanfang_pdf_merge.sh -d . -o merged_pdf.pdf
- ./wanfang_pdf_merge.sh -f "dir1/pdf1.pdf dir2/pdf2.pdf" -o output/merged_pdf.pdf
测试:
在这个基础脚本上进一步封装下,比如,对于如下的目录结构:
lox >>> tree -L 3 -p -N | grep '\[d' └── [drwxrwxr-x] wanfang ├── [drwxrwxr-x] IPTV机顶盒GUI子系统的研究与实现 │ ├── [drwxrwxr-x] Images │ └── [drwxrwxr-x] Paper ├── [drwxrwxr-x] Tools设计与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 基于QtEmbedded的图形用户界面移植 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 基于嵌入式Linux智能手机GUI平台的研究与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 基于消息通信机制嵌入式GUI的研究与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 嵌入式Linux图形用户界面的研究与开发 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 嵌入式uGUI的研究与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper ├── [drwxrwxr-x] 嵌入式系统轻量化GUI框架的设计与实现 │ ├── [drwxrwxr-x] Images │ ├── [drwxrwxr-x] Paper └── [drwxrwxr-x] 面向数字家电产品的GUI框架的设计与实现 ├── [drwxrwxr-x] Images ├── [drwxrwxr-x] Paper
我们的封装脚本命令如下:
for pdf_dir in `tree wanfang -ipNf | grep '\[d' | grep 'pdf' | awk '{print $2}'` do ~/tools/wanfang_pdf_merge.sh -d $pdf_dir done
接下来喝咖啡!!!
咖啡喝完后,我们来看一下结果:
lox >>> tree -ipNf | grep 'single' [-rw-rw-r--] ./wanfang/IPTV机顶盒GUI子系统的研究与实现/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/Tools设计与实现/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/Tools设计与实现/Paper/pdf/single_merged_pdf.ps [-rw-rw-r--] ./wanfang/基于QtEmbedded的图形用户界面移植/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/基于嵌入式Linux智能手机GUI平台的研究与实现/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/基于消息通信机制嵌入式GUI的研究与实现/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/嵌入式Linux图形用户界面的研究与开发/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/嵌入式uGUI的研究与实现/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/嵌入式系统轻量化GUI框架的设计与实现/Paper/pdf/single_merged_pdf.pdf [-rw-rw-r--] ./wanfang/面向数字家电产品的GUI框架的设计与实现/Paper/pdf/single_merged_pdf.pdf
大功告成!!!
接下来的任务是:
写论文!!!!!!!!!!