ディレクトリには、ファイル名でソートされた多くのファイルがあります。最後の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
。