Bash

ls 上的 Bash for 循環在“ (”字元處拆分行

  • October 27, 2020

目前我正在編寫一個 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 部分將在其中查找萬用字元並嘗試擴展與相應模式匹配的文件。

在這裡,看起來您實際上只想拆分lsNL 字元的輸出而不是 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使用Omglob 限定符一樣(如果沒有匹配的文件,則N(for ) 避免錯誤)。nullglob

或者,如果您有 GNU ls,請使用bash

eval "files=($(ls --quoting-style=shell-always -rt))"
for f in "${files[@]}"; do
 printf '%s\n' "$f"
done

引用自:https://unix.stackexchange.com/questions/616707