ディレクトリの最後のN個のファイルを取得するには?

ディレクトリの最後のN個のファイルを取得するには?

ディレクトリには、ファイル名でソートされた多くのファイルがあります。最後のN個(N = 4と仮定)ファイルを私のホームディレクトリにコピーしたいと思います。どうすればいいですか?

cp ./<the final 4 files> ~/

ベストアンサー1

これはbash / ksh93 / zsh配列を使用して簡単に行うことができます。

a=(*)
cp -- "${a[@]: -4}" ~/

これは、空白、タブ、改行、またはその他の難しい文字が含まれている場合でも、隠されていないすべてのファイル名に対して機能します(現在のディレクトリに隠されていないファイルが4つ以上あると仮定bash)。

どのように動作しますか?

  • a=(*)

    aこれにより、すべてのファイル名を含む配列が作成されます。 Bashから返されたファイル名はアルファベット順にソートされます。 (私の考えでは、これがまさにあなたの意味であるようです。「ファイル名で並べ替えてください。」)

  • ${a[@]: -4}

    これにより、配列の最後の4つの要素が返されますa(配列にが含まれる要素が4つ以上含まれている場合bash)。

  • cp -- "${a[@]: -4}" ~/

    これにより、最後の4つのファイル名がホームディレクトリにコピーされます。

同時にコピーして名前を変更する

a_これにより、最後の4つのファイルのみがホームディレクトリにコピーされ、コピーされたファイル名の前に文字列が追加されます。

a=(*)
for fname in "${a[@]: -4}"; do cp -- "$fname" ~/a_"$fname"; done

別のディレクトリからコピーして名前を変更します。

a=(./some_dir/*)代わりに使用すると、a=(*)ファイル名にディレクトリが追加されるという問題が発生します。 1つの解決策は次のとおりです。

a=(./some_dir/*) 
for f in "${a[@]: -4}"; do cp "$f"  ~/a_"${f##*/}"; done

別の解決策は、サブシェルを使用してcdサブシェルのディレクトリにアクセスすることです。

(cd ./some_dir && a=(*) && for f in "${a[@]: -4}"; do cp -- "$f" ~/a_"$f"; done) 

サブシェルが完了すると、シェルは元のディレクトリに戻ります。

順序が一貫していることを確認してください。

質問は、「ファイル名でソートされた」ファイルについて尋ねます。 Olivier Dulacは、彼のコメントで、この順序は地域によって異なります。システム設定に関係なく、固定結果が重要な場合は、配列を定義するaときにロケールを明示的に指定することをお勧めします。たとえば、

LC_ALL=C a=(*)

このコマンドを実行すると、現在どのロケールにあるかを確認できますlocale

おすすめ記事