使用 Mac 捷徑將文字傳送給 Shell 指令碼,讓它選取一個本機資料夾中最近修改的文字檔,並附加你的內容。本指南使用可丟棄的範例檔案,並會在資料夾為空或最新時間戳記相同時停止。

此處的任務很明確:將一段簡短內容新增至現有的純文字檔,而不必每次都手動選取該檔案。Apple 說明了 Mac 捷徑支援 Shell 指令碼。以下工作流程結合了這項受支援的功能,以及有文件說明的 zsh 檔案選取和附加行為。認識 macOS 捷徑

決定「最新檔案」的定義

本文將最新定義為最近修改。指令碼只會考慮指定資料夾內直接存放、名稱以小寫 .txt 結尾的可見一般檔案。它會排除子資料夾和符號連結。這些選取規則來自 zsh 的檔名模式與限定符。展開

這個定義會影響重複執行的結果。附加內容後,檔案的修改時間會變更,因此通常會繼續成為最新的合格檔案。如果你的目的是追蹤最新建立的文件,修改時間是不同的判定規則;請勿假設此工作流程會依建立日期選取檔案。

建立捷徑前,請選擇符合你任務的規則:

你的預期任務 此範例是否符合?
附加到最近編輯的 .txt 檔案 是
附加到檔名中日期最新的檔案 否;不會將檔名解讀為日期
附加到最近建立的檔案 否;不會使用建立時間
包含子資料夾中的檔案 否;選取範圍僅限一個資料夾
附加到 RTF 文件或 PDF 否;此範例會寫入純文字

Finder 可用來進行目視檢查。在列表顯示方式中開啟資料夾,並按一下 Date Modified 欄標題;必要時再按一次,讓最新項目排在最前面。Apple 說明了欄位排序和反轉順序的方法。Finder 的顯示可協助你檢查結果,但實際選取由指令碼自行執行。在 Mac 上的 Finder 中排序和整理項目

建立可丟棄的範例資料夾

此範例使用家目錄中的 Shortcut Append Demo 資料夾。設定流程會在同名資料夾已存在時直接停止,而不是沿用其內容。它會建立兩個合成文字檔,並間隔兩秒,讓第二個檔案的修改時間應該較新。

開啟「終端機」,貼上這段完整的設定區塊,然後按下 Return。引號括住的 heredoc 會在獨立的 zsh 程序中執行指令,因此設定失敗時會結束該程序。

/bin/zsh <<'ZSH'
emulate -L zsh
setopt ERR_EXIT
folder="$HOME/Shortcut Append Demo"

if ! /bin/mkdir "$folder"; then
  printf '%s\n' 'Setup stopped: use a new folder name if this one exists.' >&2
  exit 1
fi

printf '%s\n' 'Sample entry: blue notebook.' > "$folder/older.txt"
/bin/sleep 2
printf '%s\n' 'Sample entry: green notebook.' > "$folder/newer.txt"
printf 'Example folder: %s\n' "$folder"
ZSH

設定流程會在新資料夾成功建立後,才使用輸出重新導向建立檔案。Apple 區分了一般輸出重新導向(將指令輸出寫入檔案)和附加重新導向(將輸出加到檔案末尾)。在 Mac 上重新導向「終端機」輸入和輸出

如果設定流程指出資料夾已存在,請選擇另一個可丟棄的名稱,並在下方的設定流程和捷徑指令碼中修改資料夾指定值。請勿對已存在的資料夾重新執行個別的檔案寫入指令。

建立捷徑並保留文字輸入

在「捷徑」App 中建立新捷徑,並命名為 Append to Newest Text File。使用動作搜尋加入下列動作。Apple 說明了如何搜尋動作資料庫,以及透過 Show Info 檢查各動作接受的輸入和產生的輸出。在 Mac 上的「捷徑」中瀏覽動作列表

  1. 加入 Text 動作,內容填入合成文字 Sample entry: orange notebook.
  2. 緊接在其後加入 Run Shell Script。
  3. 將 Shell 設為 /bin/zsh。
  4. 將指令碼的輸入設為前一個 Text 動作的輸出。
  5. 將 Pass Input 設為 as arguments。
  6. 將指令碼欄位替換為下一節中的完整指令碼。

預期的連線方式是一個 Text 值傳入一個指令碼引數。指令碼會將該引數讀取為 $1。成功時,輸出會是一段包含目的地路徑的文字確認訊息;該路徑不是「捷徑」的 File 物件,輸出也不是檔案的完整內容。

請讓輸入保持連接至 Text 輸出。傳入檔案、檔名清單或捷徑的其他無關輸入,都會改變傳到指令碼的內容。指令碼會檢查引數數量,避免非預期的多筆輸入變成多條附加內容。

如果指令碼功能已停用,請開啟 Shortcuts > Settings,選取 Advanced,並啟用 Allow Running Scripts。這些是 Apple 文件中允許在捷徑內執行指令碼的設定。Apple 的指令碼設定說明

加入用來選取並附加內容的指令碼

將整段程式貼到 Run Shell Script。它不需要下載工具或另外建立指令碼檔案。資料夾指定值與上方的可丟棄範例設定相符。

emulate -L zsh
unsetopt CLOBBER APPEND_CREATE

fail() {
  printf '%s\n' "$1" >&2
  exit 1
}

(( $# == 1 )) || fail 'Expected exactly one text input.'
[[ -n "$1" ]] || fail 'The text input is empty.'

folder="$HOME/Shortcut Append Demo"
[[ -d "$folder" ]] || fail 'The example folder does not exist.'

files=( "$folder"/*.txt(N.om) )
(( ${#files} > 0 )) || fail 'No eligible .txt files were found.'

newest="${files[1]}"

if (( ${#files} > 1 )); then
  [[ "$newest" -nt "${files[2]}" ]] ||
    fail 'The newest timestamp is tied or the folder changed. Check the files.'
fi

[[ -f "$newest" && ! -L "$newest" ]] ||
  fail 'The selected file is no longer an eligible regular file.'
[[ -w "$newest" ]] || fail 'The selected file is not writable.'

if ! printf '\n%s\n' "$1" >> "$newest"; then
  fail 'Append failed; inspect the selected file before retrying.'
fi

printf 'Appended to: %s\n' "$newest"

選取運算式會建立符合條件的檔案路徑陣列。在 (N.om) 中,N 允許沒有符合項目,. 將匹配範圍限定為一般檔案,而 om 會依修改時間排序,最新檔案排在最前面。將路徑存入陣列可避免檔名中的空格造成分割。展開

接下來的檢查要求第一個檔案必須比第二個檔案新。如果兩者的修改時間相同,捷徑就會停止,不會悄悄任選一個。zsh 文件說明了用於比較檔案新舊的 -nt,以及此處使用的一般檔案、符號連結和可寫入檔案測試。條件運算式

附加指令會使用固定的 printf 格式,並將你的內容作為 %s 引數傳入。因此,內容中的百分比符號和反斜線會被視為文字,而不是額外的格式指令。開頭的換行會將內容與現有文字分開;結尾的換行則會終止該內容。如果檔案原本已以換行結尾,每筆內容之間就會多出一個空白行。Shell 內建指令

指令碼也會取消設定 CLOBBER 和 APPEND_CREATE。zsh 文件指出,取消這兩個選項後,當目的地不存在時,附加重新導向會失敗。如果選取的檔案在附加前消失,這點很重要:指令碼應回報失敗,而不是在原路徑建立替代檔案。重新導向

使用範例檔案檢查結果

執行捷徑一次。範例資料夾尚未變更時,預期目的地是 newer.txt。開啟該檔案,確認內容如下。這是根據範例推得的預期結果,並不代表已完成 Mac 介面測試。

Sample entry: green notebook.

Sample entry: orange notebook.

也請開啟 older.txt。它應仍只包含 Sample entry: blue notebook.。檢查這兩個檔案,可同時確認任務的兩個部分:選取一個目的地,並保留另一個檔案。

將 Text 動作改為 Sample entry: yellow notebook.,再執行一次,測試第二筆合成內容。只要沒有其他合格檔案變得更新,就會在 newer.txt 中看到另一筆分隔開的內容。若使用相同輸入執行捷徑兩次,該輸入會被附加兩次;此程式不會偵測重複內容。

本文依照文件檢查了這些範例,但未在此處執行:目前可用的環境既沒有 macOS 捷徑,也沒有 zsh。將資料夾指定值改作他用前,請先在 Mac 上完成可丟棄檔案的檢查。

了解空資料夾、名稱衝突和檔案變動

此工作流程需要一個已存在的目的地。如果資料夾不存在、資料夾為空,或其中只包含不符合條件的項目,就會在附加前產生錯誤。它不會建立預設檔案、選取子資料夾,或改用其他名稱的文件。

避免建立目的地可處理名稱衝突。若設定流程發現資料夾名稱已存在,就會停止。在一般捷徑執行期間,選取的檔案會保留原名:指令碼不會重新命名,也不會另存副本。另一種檔案遺失情況的處理方式則由有文件說明的 zsh 附加選項控制。重新導向

如果結果與預期不同,請依序進行以下簡短診斷:

  1. 檢查資料夾指定值。 它必須與設定時建立的資料夾相符。
  2. 檢查檔案是否符合條件。 範例模式會包含資料夾頂層中可見、名稱以小寫 .txt 結尾的一般檔案。
  3. 檢查修改時間排序。 在 Finder 中查看 Date Modified,並記得編輯檔案可能使它成為下一個目的地。
  4. 檢查時間戳記是否相同。 稍後編輯並儲存預定的範例檔案,再次查看排序結果。
  5. 檢查動作連線。 一個文字值必須以一個引數傳入 Shell。

此指令碼適用於執行期間內容保持不變的資料夾。選取和寫入是分開的操作:其他程序可能在這兩者之間編輯、替換或新增檔案。這些檢查不會讓工作流程具備交易特性;寫入失敗也可能留下部分附加內容。發生附加錯誤後,重試前請先檢查檔案。

原生檔案篩選器的適用情況

Apple 說明了 Filter Files 動作:它接受內容,使用篩選條件縮小範圍,並將符合條件的結果傳給後續動作。其一般篩選控制項可排序結果並限制項目數量。這些操作有助於選取檔案,但本身不會附加文字。「尋找」和「篩選」動作簡介、新增篩選參數

此指南將選取和寫入放在同一個 Shell 指令碼中,讓檔案模式、時間相同時的處理方式,以及目的地必須已存在等條件都明確可見。如果你用檔案動作建立不同的流程,請先查看每個動作的 Show Info:File 結果、轉換成 Text 的檔案內容,以及以 Text 表示的路徑,是不同的值。Apple 提供這些動作說明,正是為了指出輸入和輸出類型。在 Mac 上的「捷徑」中瀏覽動作列表

範例符合預期後,改用時請維持相同的明確條件:一筆文字內容、一個指定的本機資料夾,以及一個修改時間明確最新且符合條件的檔案。如此一來,每次執行的結果都可預期,而且捷徑停止時,你也有明確的檢查方向。

來源