Bash
ls 上的 Bash for 循環在“ (”字元處拆分行
目前我正在編寫一個 bash 腳本,該腳本應該按照創建日期的順序遍歷目錄中的一些文件。為此,我使用(使用真實程式碼而不是
echo
):for i in $(ls -tr) do echo $i done
大多數情況下都可以正常工作。
但現在我發現了一種破壞腳本的文件:
aha_-_a ()a.txt
.此文件名包含一個空格,後跟一個左括號“ (”,這似乎觸發了換行符。結果是:
aha_-_a ()a.txt
但它應該是:
aha_-_a ()a.txt
您知道如何獲得所需的行為嗎?
不加
$(ls -tr)
引號會在展開時呼叫 split+glob。拆分是基於
$IFS
(預設為 SPC、TAB 和 NL)的字元完成的,然後 glob 部分將在其中查找萬用字元並嘗試擴展與相應模式匹配的文件。在這裡,看起來您實際上只想拆分
ls
NL 字元的輸出而不是 glob 部分。所以應該是:IFS=$'\n' # split on NL only set -o noglob # disable the glob part for f in $(ls -tr); do printf '%s\n' "$f" done
這將適用於包含 SPC 字元的文件。但是,如果有帶有 NL 字元的文件名,它仍然無法工作。
在這裡,最好是切換到
zsh
並執行:for f in *(NOm); do printf '%s\n' "$f" done
where
*
擴展為目前目錄中按年齡反向排序的所有非隱藏文件,就像ls -rt
使用Om
glob 限定符一樣(如果沒有匹配的文件,則N
(for ) 避免錯誤)。nullglob
或者,如果您有 GNU
ls
,請使用bash
:eval "files=($(ls --quoting-style=shell-always -rt))" for f in "${files[@]}"; do printf '%s\n' "$f" done