Bash

按文件的基本名稱對文件的路徑名數組進行排序

  • March 12, 2021

假設我有儲存在數組中的文件的路徑名列表

filearray=("dir1/0010.pdf" "dir2/0003.pdf" "dir3/0040.pdf" ) 

我想根據文件名的基本名稱按數字順序對數組中的元素進行排序

sortedfilearray=("dir2/0003.pdf" "dir1/0010.pdf" "dir3/0040.pdf") 

我怎樣才能做到這一點?

我只能對他們的基本名稱部分進行排序:

basenames=()
for file in "${filearray[@]}"
do
   filename=${file##*/}
   basenames+=(${filename%.*})
done
sortedbasenamearr=($(printf '%s\n' "${basenames[@]}" | sort -n))

我在考慮

  • 創建一個關聯數組,其鍵是基名,值是路徑名,因此始終通過基名訪問路徑名。
  • 僅為 basenames 創建另一個數組,並應用於sortbasename 數組。

謝謝。

sort在 GNU coreutils 中允許自定義欄位分隔符和鍵。您設置/為欄位分隔符並根據第二個欄位進行排序,以根據基本名稱而不是整個路徑進行排序。

printf "%s\n" "${filearray[@]}" | sort -t/ -k2會產生

dir2/0003.pdf
dir1/0010.pdf
dir3/0040.pdf
oldIFS="$IFS"; IFS=$'\n'
if [[ -o noglob ]]; then
 setglob=1; set -o noglob
else
 setglob=0
fi

sorted=( $(printf '%s\n' "${filearray[@]}" |
           awk '{ print $NF, $0 }' FS='/' OFS='/' |
           sort | cut -d'/' -f2- ) )

IFS="$oldIFS"; unset oldIFS
(( setglob == 1 )) && set +o noglob
unset setglob

對名稱中帶有換行符的文件名進行排序將導致該sort步驟出現問題。

它生成一個/-delimited 列表,awk其中包含第一列中的基本名稱和其餘列中的完整路徑:

0003.pdf/dir2/0003.pdf
0010.pdf/dir1/0010.pdf
0040.pdf/dir3/0040.pdf

這是已排序的內容,cut用於刪除第一個以/- 分隔的列。結果變成了一個新的bash數組。

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