かなり簡単なスクリプトを作成しようとしていますが、特定のファイルをスキップする合理的な方法が見つかりません。
与えられた順序ですべてのファイルをリストしたいと思います。リストに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}"
。
データを削除するすべてのタスクと同様に、すべてのソリューションをテストします。コピー実際に実行する前に実際のデータを取得してください。
答え2
あなたがしようとしていることについて非常にあいまいな説明を提供したので、この答えも同様にあいまいになるかもしれませんが、
head
そしてtail
この目的のために設計されています。
最初の10個の結果を除くすべての結果を無視するには、次のようにします。
head -n 10
最後の10件の結果を除くすべての結果を無視するには、次のようにします。
tail -n 10
注:これは結果が改行で区切られている場合にのみ機能します。