ファイル名を取得し、サイズでリストを並べ替え、リストからコマンドを実行する小さなスクリプトを作成しようとしています。これまで私は以下を持っています:
#!/bin/bash
filenames="one \
two \
three"
for i in $filenames; do
...
done
うまくいきますが、forコマンドを押す前にファイルサイズでリストをソートしたいと思います。
答え1
ファイル名に改行文字が含まれておらず、システムにGNUがある場合は、次のことがstat
できます。
- 配列変数の使用
filenames
stat
各ファイルのサイズとファイル名を印刷し、結果sort
(逆数)を使用してから最初のフィールド(サイズ)を削除して、cut
ファイル名をサイズでソートする(最も大きいものから)。- さらなる処理のために、結果を
while
ループに供給します。
filenames=( one two three )
while IFS= read -r file; do
echo "do something with $file"
done < <(stat --printf '%s\t%n\n' -- "${filenames[@]}" | sort -nr | cut -f2-)
上記と同じですが、ヌル文字を区切り文字として使用します(ファイル名に改行文字が含まれていないことを保証できない場合は、GNUsort
とGNUも必要ですcut
)。
filenames=( one two three )
while IFS= read -r -d $'\0' file; do
printf 'do something with %s\n' "$file"
done < <(stat --printf '%s\t%n\0' -- "${filenames[@]}" | sort -znr | cut -zf2-)
タイプのファイル名に注意してください。シンボリックリンク、リンク自体のサイズ(リンクが指すファイルのサイズではない)が考慮されます。変更-L
するにはオプションを追加してください。stat
標準入力で開かれたファイルとして解釈されるという名前のファイルでは機能しません-
。stat
使用./-
して解決してください。
答え2
のzsh
ような方法以下は、mtimeによるソートに関する同様の質問に対する答えです。、それ自体は以下で適応されています。それ、任意の順序で配列を並べ替えます(詳細は後者を参照)。
zmodload zsh/stat
array=(one two three...)
# store sizes in an "A"ssociative array:
typeset -A size
stat -nL -A size +size -- $array
# sort using the oe glob qualifier "n"umerically
sorted_array=(/(e['reply=($array)']noe['REPLY=$size[$REPLY]'])