かなり簡単なスクリプトを作成しようとしていますが、特定のファイルをスキップする合理的な方法が見つかりません。
与えられた順序ですべてのファイルをリストしたいと思います。リストに10個以上のファイルが含まれている場合は、11-nファイルを削除して最初の(または最後の)10個のファイルを保持したいと思います。
/TLDR: 次のコマンドにパイプする前に find/ls/whatever 結果から固定数のファイルをスキップする方法
指定されたパターンを持つすべてのファイルを名前でソートし、10個以上の場合は削除したいと思います。
ベストアンサー1
使用zsh
モード
*(.[11,-1])
現在のディレクトリにある一般ファイルのすべての名前(ディレクトリ名などを除く)を一致させ、名前でソートし(デフォルトのソート順)、最初の10を除くすべての名前を返します。
テスト:
$ touch file-{01..20}
$ ls
file-01 file-03 file-05 file-07 file-09 file-11 file-13 file-15 file-17 file-19
file-02 file-04 file-06 file-08 file-10 file-12 file-14 file-16 file-18 file-20
$ printf '%s\n' *(.[11,-1])
file-11
file-12
file-13
file-14
file-15
file-16
file-17
file-18
file-19
file-20
あなたはしたいですか?削除次のファイル:
$ rm *(.[11,-1])
$ ls
file-01 file-02 file-03 file-04 file-05 file-06 file-07 file-08 file-09 file-10
この点に注意してください必要zsh
他のシェルと同様に、このシェルはbash
使用される特殊なタイプのワイルドカードパターンを理解していません。
他のシェルで利用可能
zsh -c 'rm *(.[11,-1])'
次bash
のようなことができます
names=( * )
printf '%s\n' "${names[@]:10}"
削除するファイル名をリストしますが、リストされた名前が通常のファイルの名前であるか、ディレクトリ名である可能性が高いという保証はありません。したがって、以下を繰り返すことができます。
for name in *; do
if [ -f "$name" ]; then
files+=( "$name" )
fi
done
printf '%s\n' "${files[@]:10}"
これにより、一般ファイルを指すシンボリックリンクの名前も取得されます。
これを削除するには、を使用しますrm "${files[@]:10}"
。
データを削除するすべてのタスクと同様に、すべてのソリューションをテストします。コピー実際に実行する前に実際のデータを取得してください。