変更された日付でzsh配列をソートする方法は?

変更された日付でzsh配列をソートする方法は?

変更された日付でzsh配列をソートする方法は?

files=( ~/a ~/b ~/c )
# how to sort files by date?

PS:これは私の正確なユースケースです。 (fzほぼfzf

v () {
 local files
 files=() 
 command rg '^>' ~/.viminfo | cut -c3- | while read line
 do
  [ -f "${line/\~/$HOME}" ] && files+="$line" 
 done
 test -f ~/.emacs.d/.cache/recentf && {
  command rg --only-matching --replace '$1' '^\s*"(.*)"$' ~/.emacs.d/.cache/recentf | while read line
  do
   [ -f "$line" ] && files+="$line" 
  done
 }
 files="$(<<<"${(F)files}" fz --print0 --query "$*")"  || return 1
 files="${files//\~/$HOME}" 
 local ve="$ve" 
 test -z "$ve" && ! isSSH && ve=nvim 
 "${ve:-vim}" -p ${(0@)files}
 : '-o opens in split view, -p in tabs. Use gt, gT, <num>gt to navigate tabs.'
}

ベストアンサー1

リストを作成しながらソートしておくと、はるかに簡単になると思います。。しかし、できないなら…

従来のアプローチは、データにソート基準を追加してからソートし、追加したジャンクを削除することです。タイムスタンプとファイル名を含む配列を明確にし、タイムスタンプがアルファベット順に並べ替えることができる形式で構成します。配列の並べ替え(使用o パラメータ拡張フラグ)を選択してプレフィックスを削除します。あなたはそれを使用することができますstatモジュールはファイルの修正時間を取得します。

zmodload zsh/stat
for ((i=1; i<$#files; i++)); do times[$i]=$(stat -g -F %020s%N +mtime -L -- $files[$i]):$files[$i]; done
sorted=(${${(o)times}#*:})

zstat形式%N(ナノ秒解像度でタイムスタンプを取得する)には、zsh≥5.6が必要です。 zshが古くなっている場合、それを削除するとコードは機能しますが、タイムスタンプを1秒の解像度で比較します。多くのファイルシステムには1秒未満の解像度がありますが、stat以前のバージョンのzshではzshモジュールを使用して取得することはできません。

zshが古すぎる場合は、このstatユーティリティを使用してより正確なタイムスタンプを取得できます。GNUコアツール。お持ちの場合は、おそらく他のGNU coreutilもお持ちであるので、私はそれを使用します。 GNU coreutilsは通常非埋め込みLinuxに存在しますが、BSDやmacOSには存在しない可能性があります。 macOSでは使用できますbrew。 GNU coreutilsがデフォルトのオペレーティングシステムの一部ではない場合は、に変更する必要がstatあります。gstatsortgsortcutgcut

if (($#files)); then
  sorted=(${(0@)"$(stat  --printf='%040.18Y:%n\0' "$files[@]" | sort -rz | cut -z -d':' -f2-)"})
else
  sorted=()
fi

$files別のzshアプローチは、すべてのファイルなどを含むスキーマを構築することです。このパターンに一致するファイルを並べ替え、必要なファイルのみを含めるようにフィルタリングします。実際にはスキーマ全体を構築する必要がありますが、more_filesこれは必ずしも実用的ではないかもしれません。

more_files=(~/*(Om))
sorted=(${more_files:*files})

おすすめ記事