Bash

bash 命令在目錄中創建包含 10 個最新圖像的數組?

  • April 20, 2019

我正在編寫一個 bash 腳本,我需要在目前目錄中創建一個包含10 個最新圖像文件(從新到舊)的數組。

我認為“圖像文件”是具有某些副檔名的文件,例如.jpg.png. 我只需要支持幾種特定的圖像類型,我也可以用一個正則表達式來表達這一點,比如"\.(jpg|png)$".

我的問題是,如果我嘗試這樣做,例如$list=(ls -1t *.jpg *.png | head -10)結果文件列表會以某種方式成為一個元素,而不是每個文件名都是我數組中的一個單獨元素。

如果我嘗試使用$list=(find -E . -iregex ".*(jpg|png)" -maxdepth 1 -type f | head -10),我不確定如何按日期/時間對列表進行排序並僅保留文件名。還 find 似乎放在./每個文件的前面,但我可以用sed. 而且find我仍然有我的整個列表成為$list數組中的一個條目的問題。

正確的語法是:

list=($(ls -t *.jpg *.png | head -10))
echo First element: ${list[0]}
echo Last element: ${list[9]}

但是,此解決方案會出現包含空格字元(或一般的任何空格)的文件名的問題。

對於bash≥ 4:

要將命令的輸出逐行讀取到數組中,您應該使用readarray

readarray files < <(ls -1t *.jpg *.png | head -10)

…或mapfile

mapfile -t files < <(ls -1t *.jpg *.png | head -10)

除此以外:

files=()
while IFS= read -r f; do
   files+=( "$f" )
done < <(ls -1t *.jpg *.png | head -10)

另請參閱


但是,文件名允許有換行符,因此對於讀取文件名,您應該使用find和使用\0分隔符而不是ls -1使用\n分隔符:

files=()
while IFS=  read -r -d $'\0' f; do
   files+=("$f")
done < <(
   find . -maxdepth 1 -type f \
     -regextype posix-extended -iregex ".*\.(jpg|png)$" \
     -printf '%T@\t%P\0' \
   | sort -nrz \
   | head -z -n 10 \
   | cut -z -f2-
)

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