regexp 的網路應用實例

挑剔地抓檔案

為了尊重智慧財產權, 又不要增加學生的經濟負擔, 我經常上網抓免費的講義。 例如為了要上數值方法的課, 就用 "numerical method lecture notes" 去 google, 結果找到 這份講義, 裡面有好幾個 pdf 檔。 當然你可以用 wget 或是其他砍站軟體把它全部抓下來; 不過砍站軟體就只能抓檔案。 我們接下來卻是要用 regexp 來達成相同的任務。 單就抓檔案而言, 這種方式固然比不上砍站軟體 (例如無法輕易地遞迴); 但抓檔案不過是這種方法的一個 例子, 如果您學會這招的精神, 它其實可以應用在: 選擇性複製檔案, 選擇性擷取 e-mail 位址並一次寄出, 選擇性擷取通訊錄資料並一口氣轉成手機的通訊錄檔案, ... 等等, 甚至應用在筆者也無法想像的其他許多場合。

先用文字瀏覽器 lynx 把索引頁抓下來: lynx -source http://ads.harvard.edu/books/1990fnmd.book/ > nm.html 注意: lynx 本來可以拿來瀏覽網頁; 但這裡我們看都不看就直接將網頁存檔。 命令列用戶真的很奇怪, 總是有一些跟平常 GUI 用戶很不同的做法, 是吧? 但是這裡秀 lynx 這招不是為了耍酷而已, 等一下馬上會發現為什麼它這招把 firefox 與 IE 都比下去。

less nm.html 檢視文件內容, 發現我們要抓的 pdf 檔案都很簡單: 檔名都是文數字。 請下: perl -ne 'print "$1\n" if /href\s*=\s*"(\w+\.pdf)/i' nm.html 應該列出 10 個 pdf 檔名, 每個檔名一列。 這裡的 $1 對應到比對字串中的第一對小括弧, 也就是檔名。 翻譯成中文就是: "只要抓到超連結裡面的 xxx.pdf 就把這個檔名印出來"。 又, \n 代表換列; 如果沒有 \n 所有檔名會擠在一起。 最後面的 i 表示忽略大小寫。

先建立一個空的 目錄 (directory) 叫做 nm 好了, 並進到裡面去工作, 以免等一下抓來的檔案跟 家目錄 (home directory) 其他檔案混在一起:

        mkdir nm
        pwd
        cd nm
        pwd

注意, 要表演魔術了: 按幾次上箭頭, 把剛才的 perl 指令叫回來修改, 在 print 裡面多加一些東西:
perl -ne 'print "lynx -source http://ads.harvard.edu/books/1990fnmd.book/$1 > $1\n" if /href\s*=\s*"(\w+\.pdf)/i' nm.html
請剪貼上面指令, 全部串在一列上面。 如果分成幾次貼上, 中間不要換列, 但記得要補上空格。 看它印出什麼? 神奇吧? 別人用程式產生資料; 我們 用資料產生程式! (如果把指令也算做是程式的話啦) 且慢, 還沒有完。 perl 只是把我們想下的指令印出來; 我們只是自己看了高興而已; 實際上並未執行。 要把印出來的指令進一步用 pipe 機制餵給命令列解譯程式 bash 執行, 才會真的生效。 請先下 ls -l 確認一下目前尚未下載任何檔案, 然後再用上箭頭叫出先前指令, 在最後面補上一小段, 變成:
perl -ne 'print "lynx -source http://ads.harvard.edu/books/1990fnmd.book/$1 > $1\n" if /href\s*=\s*"(\w+\.pdf)/i' nm.html | bash

這個, 才是學電腦。

我一直希望打破今日大眾資訊教育當中, 對於滑鼠選單的迷信, 及對於指令的盲目恐懼:

  1. 重複, 機械化, 有規律的動作, 就不應該是人做的事! 用滑鼠來做, 並沒有比較高明;
  2. 指令並不比英文數學可怕, 就像非英文系也可以托福高分, 非數學系也可以是數學高手一樣, 非資訊科系的人也絕對可以學會下指令

軟體公司的愚民政策及文宣一直告訴我們: 指令太可怕太不人性, 非資訊科系的人學不起來也不需要學; 我深深不以為然。 建議經常拿英文數學教育來跟資訊教育對照, 您就會發現今日的大眾資訊教育的荒謬之處, 也將更能掌握 長線投資的電腦學習策略

[待補充]

請提供更多 "regexp 應用於網路" 的問題; 我來幫您解決, 並以講義分享。