KeyboardMaestro_PathFinder_依次處理多個選中檔案

wait4friend發表於2018-05-09

需求場景

我選中一個目錄下的多個檔案,然後對這一批檔案進行相同或類似的操作。比如我選中幾個md檔案,然後對所有檔案中的圖片地址進行更新,這樣就可以把本地儲存的圖片檔案轉移到其他目錄,甚至換成圖床的地址。

思路描述

  1. 在Path Finder中選擇一個或多個檔案;
  2. 呼叫KM(Keyboard Maestro)巨集,取出所選檔案的全路徑列表;
  3. 遍歷上一步得到的列表,呼叫shell依次處理每一個檔案;

獲取選中檔案的路徑

原生KM提供了一個For Each Path in Finder Selection的Action,只支援對Finder中選中的檔案進行操作。因為我基本使用Path Finder進行日常操作,所以我需要實現一個PF版本的類似操作。考慮到實現一個Action的門檻較高,所以暫時選擇使用Macro來實現。原來是打算使用AppleScript來實現,不過最近看到MacOS提供了JXA模式,用JavaScript來操作OS級別的任務。所以儘量使用JXA來實現我的需求。

基礎版

僅支援單一目錄下的檔案

KM提供了Execute JavaScript for Automation的Action,在程式碼框中輸入下面的程式碼。或者把程式碼儲存為.js檔案,在Action中直接呼叫檔案。

// 獲取每個檔案的地址
function pathFolderFile(x) {
    var strPath = x.posixPath();
    return strPath;  
}

// 獲取Path Finder中選中的檔案地址,如果是多個檔案,就用\n符號進行分割
function run() {
    var pfSeln = Application("Path Finder").selection();
    var selectionList = pfSeln ? pfSeln.map(pathFolderFile) : [];  
    return selectionList.join("\n");  

}
複製程式碼

上面的程式碼整體上很簡單,幾個重點如下:

  • 如果沒有選中任何檔案,就返回空列表,避免後續操作出錯。
  • 最終需要把多個path結果返回到一個變數中供下一步操作,但是我目前使用的KM7沒有提供List型別的變數,所以我把List的結果轉換為一個用換行符分隔的字串。
  • Action中一定要設定 save variable to ,把JXA返回的結果存在變數中。

高階版

增加對資料夾的遞迴操作。

暫時沒有找到JXA的處理方式,待續。。。

依次處理返回的檔案列表

KM提供了For Each這個Action,對剛才返回的字串可以根據換行符進行逐行操作。這個和python等語言裡面的 for X in Y 結構是一樣的,很容易理解。如下圖

image-20180506205558482

呼叫Shell指令碼的坑

KM中的Execute a Shell Script操作,使用的是非互動式模式。即,當在KM中呼叫shell的時候,不會使用當前使用者的環境變數。這和通過crontab呼叫shell的場景是一模一樣的。因為最開始忽略這個細節,所以出現兩個問題

  1. 呼叫python的時候,用了系統預設的2.7版,而不是3.5版。
  2. 在處理UTF-8字符集的時候報錯,因為沒有設定 export LANG=zh_CN.UTF-8。

解決這個問題的辦法也很簡單,和crontab執行程式碼一個套路,只需要在執行shell之前先執行當前使用者的環境配置檔案。如下

# 設定環境變數
source ${HOME}/.bash_profile
複製程式碼

完整的KM Macro

這裡把JXA儲存為.js檔案進行呼叫

image-20180506205159771

相關文章