【復盤】文檔批量切割與轉換:python + pandoc + shell

背景

現有一 Markdown 文件,其中有 50 個小組塊,組塊之間以二級標題區分。每個二級標題下有 1 張圖片,然后是文字。

以下是文檔中部分內容示例:

## 1. 小明

![](小明打羽毛球的球場網址)

今天小明去打羽毛球。

## 2. 小紅

![](小紅逛街的商店網址)

今天小紅去逛街。

現在希望:

  • 把這 50 個組塊單獨切割出來
  • 每個組塊均轉換為 doc 文件
  • 文件名為小標題名(只有中文,不含數字序號)
  • 每個小組塊文件中,以小標題為內文標題(只有中文,不含數字序號)

問:

如何批量完成該工作?

任務拆分

  1. 將 1 個 md 文件批量切割 md 文件 為 50 個 md 文件
  2. 切割的同時,將小標題作為文件名取出并直接為每個組塊文件命名
  3. 將 50 個 md 文件批量轉換成 50 個 doc 文件

工具準備

  • python:撰寫批量切割的 python 腳本
  • pandoc:用于格式轉換
  • bash:通過 shell 腳本實現批量的格式轉換;有可能需要用上批量重命名的命令 rename 來進行邊角修改

任務 1: 批量切割文檔

首先思考:

如果是手動切割,過程是怎樣的?

顯然我們是以二級標題為切割標志的。而二級標題的代碼是 ##,會不會在文中其他地方出現呢?

進一步觀察與思考會發現:切割標志其實不是 ##,而是 \n## ——也就是說,段落中或者網址中出現的 ## 都不是二級標題的代碼,只有換行符 \n## 連續出現時,## 才是二級標題代碼。因此我們確定了切割標志為:(字符串)\n##

python 中字符串的 str.split(sep, maxsplit) 方法可接受 2 個參數[1]

  1. 第 1 個參數 sep 表示分割標志(這里是 \n##
  2. 第 2 個參數 maxsplit 表示最多分割幾次(由于是 50 份,故應該切割 49 次)

所以將讀入的全文以小標題為界分割為 50 份字符串的關鍵代碼是:

# 已將全文讀入 finContent 中
sp50 = finContent.split("\n##", 49)

任務 2:批量將已切割好的字符串導出到 50 個 md 文件中,并以各小標題為各文件命名

批量導出到 50 個 md 文件中并不難,如果沒有上述命名需求,那么直接一個迭代 50 次的 for 循環即可解決該問題。

問題在于:

如何取得各小標題名并為新生成的文件命名?

觀察每個小組塊,發現規律:

  1. 每個二級標題中都有英文句號「.」,在「.」后的部分,除去空格,即為小標題所有文字,這意味著:只要取得小標題所在行的內容,就可以用 str.split() 方法取得小標題對應文字
  2. 二級標題下即為圖片代碼,也就是說對這 50 個字符串而言,每個字符串可以 \n\n![]( 為分割標志,從而取得小標題所在行的內容

因此取得小標題的關鍵代碼為:

index = ((((iStr.split("\n\n![](")[0]).split('.'))[1]).split(' '))[1]

綜合前 2 項任務,該腳本代碼如下(同時放在 GitHub 庫中):

#coding: utf-8

originPath = "/home/sushangjun/Documents/"
srcPath = originPath + "Top50Bussiness.txt"
tarPath = originPath + "output50/"

fin = open(srcPath, 'r')

finContent = fin.read()

sp50 = finContent.split("\n##", 49)

for iStr in sp50:
    index = ((((iStr.split("\n\n![](")[0]).split('.'))[1]).split(' '))[1]
    fout = open(tarPath + "{}.md".format(index), 'w')
    fout.write("## " + index + "\n\n![](" + (iStr.split("\n\n![]("))[1])
    fout.close()

fin.close()

在命令行中執行該腳本,即可完成批量切割任務。

任務 3: 批量轉換格式

這里需要使用 Pandoc[2],Debian 系 Linux 只要使用 apt-get 安裝即可:

$ sudo apt-get install pandoc

完成后,輸入 pandoc --version 查看是否安裝成功。

若安裝成功,只要下述命令,即可將 a.md 轉換為 a.doc

$ pandoc a.md -o a.doc -c Github.css

但是這只能實現單文件的格式轉換,若需要多文件的格式轉換,顯然需要批處理。對 *nix 稍有了解的人很容易聯想到使用 bash shell 來解決這個問題:

  1. 讀取目錄下的文件列表
  2. 對讀取的每個文件名執行上述 pandoc 命令

由于事情緊急,因此查找網絡資料后,在命令行中輸入下述命令,完成文件格式批量轉換:[3]

注:下述操作均默認在 50 個 md 文件所在目錄下進行

$ ls > aa.md
$ cat aa.md |while read line
> do
> pandoc $line -o $line.doc -c Github.css
> done

這樣基本完成了批量格式轉換問題。但有 1 點不美:那就是在此操作下,得到的文件后綴是 .md.doc 而非 .doc。如何解決這個問題呢?最后我們就使用 rename 方法搭配簡單的正則表達式,完成該任務:[4]

rename 's/\.md.doc/\.doc/' *

相關代碼也已經寫成 shell script 形式上傳到 GitHub 庫中.

參考資料


  1. Python 3.5: str.split ?

  2. Markdown寫作進階:Pandoc入門淺談 ?

  3. shell 循環文件列表取出文件名 ?

  4. Linux批量修改文件名方法小結 ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容