ファイル名Xからファイル名Yに複数のファイルをコピーしますか?

ファイル名Xからファイル名Yに複数のファイルをコピーしますか?

私がしたいのは、辞書の範囲内のファイルをコピーすることです。

ファイルの例:

-rw-r--r--   1 root root   15276 Oct  5  2004 a2ps.cfg
-rw-r--r--   1 root root    2562 Oct  5  2004 a2ps-site.cfg
-rw-r--r--   4 root root    4096 Feb  2  2007 acpi.txt
-rw-r--r--   1 root root      48 Feb  8  2008 adjtime.jpg
-rw-r--r--   4 root root    4096 Feb  2  2007 alchemist.jpg

使用例:

  • 3つのファイルをからにコピーしますasps.cfgacpi.txt
  • 3つのファイルをからにコピーしますa2ps-site.cfgadjtime.jpg
  • 4つのファイルをからにコピーしますa2ps-site.cfgalchemist.jpg

それでは、一連のファイル(ファイル名Xからファイル名Yまで)をディレクトリにコピーする方法はありますか?

良い:cp filenameX ... filenameY destination/

答え1

一般的なアプローチは、一連のファイル名を印刷するシェル関数を定義することです。この関数の単純なバージョンは、現在のディレクトリの2つのファイル名の間にあるすべてのファイルを一覧表示します。

range()
{
    ls | sed -n "/^$1\$/,/^$2\$/p"
}

これはsed範囲を使用して、指定された2つの文字列($1と)$2の間のすべての項目を印刷します。

cp(1)その後、コマンドでこの機能を使用できます。

cp $(range asps.cfg acpi.txt) /destination/path

ファイル名にスペースが含まれていると、この操作は失敗します。これを行うにはもう少し洗練されなければなりません。

range asps.cfg acpi.txt | xargs -d '\n' -I {} cp {} /destination/path

ファイル名に改行文字(\ n)が含まれていると、操作は失敗します。そうなる可能性はほとんどないので、この問題を解決することは読者の練習問題として残しておきます。

これを他のシェル関数にまとめることができます。

cprange()
{
    [ $# -eq 3 ] || { echo "usage: cprange start end dir" >&2; return 1;}
    range "$1" "$2" | xargs -d '\n' -I {} cp {} "$3"
}

次のように使用してください。

cprange filenameX filenameY destination

範囲は、現在のディレクトリのファイル名にのみ適用されることに注意してください。これをさまざまな方法で拡張できます(ディレクトリパラメータの追加range、パラメータからrange使用へのパス抽出dirnameなど)。しかし、要求事項に応じて決定させていただきます。詳細が必要な場合はこちらまでお問い合わせください。

答え2

Zshには、globの結果からさまざまなファイルを選択する簡単な方法があります(globはワイルドカード一致です)。利点は、コマンドが書くのが短いことです。マイナスサイトでは、書き込むファイルのシーケンス番号を調べる必要があります。たとえば、次のコマンドは、.jpg現在のディレクトリから拡張子を持つ21番目、22番目、...、40番目のファイルをコピーし、ファイルはアルファベット順に一覧表示されます。

cp *.jpg([21,40]) destination/

Zshには役に立つかもしれないし、そうでないかもしれないオプションがあります。 under setopt numeric_glob_sort, foo9bar.jpgwill sort before foo10bar.jpg. cp *.jpg(om[21,40]) destination/21番目から40番目までの最新のファイルを選択するなど(O大文字を使用して逆順にソート)、glob修飾子で別のソート順序を選択することもできます。バラよりグローバル予選マニュアルの詳細をご覧ください。

すべてのシェルでファイルを繰り返して、記録する最初のファイルからコピーを開始し、最後のファイル以降に停止するループを作成できます。警告、テストされていません。

in_range=
for x in *.jpg; do
  if [ "$x" = "first-file.jpg" ]; then in_range=1; fi
  if [ -n "$in_range" ]; then cp "$x" destination/; fi
  if [ "$x" = "last-file.jpg" ]; then break; fi
done

答え3

この例で最も簡単なのは、M-* を使用してパターンを完成させ、コピーしたくないパターンを削除することです。

% cp *[hit Escape and press *]
->
% cp file1 file2 file3 file4 ... 

次に、コピーしたくないファイルを手動で削除します。とにかく、これはシェル機能ではありませんcp

必要に応じてパターンをトリミングできます。ディレクトリに他の多くのファイルがあり、で始まるファイルだけをコピーしたい場合は、aその文字でパターンを開始できます。ファイル名のグロービングに関するシェル文書を参照することもできます。例えば、http://tldp.org/LDP/abs/html/globbingref.html

答え4

ファイル名をまとめて同じ分量で配布しているようですね。

すべてのファイル名を1つのファイルに保存

ls > all_files

ファイルをバッチに分割

split -l 4 all_files all_files-

各ファイルには4つのファイル名があります。all_files-*

一つを選んで話してコピーしてall_files-aaみてください。

xargs -I{} cp {} folder_for_batch_1 < all_files-aa

関連情報