私がしたいのは、辞書の範囲内のファイルをコピーすることです。
ファイルの例:
-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.cfg
。acpi.txt
- 3つのファイルをからにコピーします
a2ps-site.cfg
。adjtime.jpg
- 4つのファイルをからにコピーします
a2ps-site.cfg
。alchemist.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.jpg
will 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