スクリプト:n個のファイルをスキップ

スクリプト:n個のファイルをスキップ

かなり簡単なスクリプトを作成しようとしていますが、特定のファイルをスキップする合理的な方法が見つかりません。

与えられた順序ですべてのファイルをリストしたいと思います。リストに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}"

データを削除するすべてのタスクと同様に、すべてのソリューションをテストします。コピー実際に実行する前に実際のデータを取得してください。

おすすめ記事