ワイルドカードを介して複数のファイルをコピーする方法は?

ワイルドカードを介して複数のファイルをコピーする方法は?

ABC.*という多くのファイルを含むフォルダがあります(これらのファイルは約100個あります)。 DEFで始まる名前の新しいファイルにすべてコピーしたいです。 *

だから私は欲しい

ABC.Page1
ABC.Page2
ABC.Topic12
...etc

にコピー

DEF.Page1
DEF.Page2
DEF.Topic12
...etc

BASHまたは同様のバッチコマンドを使用してこれを行う最も簡単な方法は何ですか? sed、awk、xargsに関連する問題を考えていますが、構文を特定するのに問題があります。 Pythonスクリプトを書くこともできますが、あまり複雑ではないコマンドラインソリューションがあるかもしれないと思いました。

答え1

Bashでこのようなものはどうですか?

for file in ABC.*; do cp "$file" "${file/ABC/DEF}";done

cpコマンドの前にechoを追加することでこれをテストできます。

for file in ABC.*; do echo cp "$file" "${file/ABC/DEF}";done

答え2

cp多数のファイルを効率的に処理するには、各ファイルに対して別のプロセスを開始しないことをお勧めします。 1つの方法は、コピーして次のように名前を変更することですprenamerenameDebianベースのディストリビューションのデフォルトのシンボリックリンクはこれです)。 Linuxでこれを使用してくださいmktemp

tmp=$(mktemp -d --tmpdir=.)
cp ABC.* "$tmp"
prename "s:$tmp/ABC:DEF:" "$tmp/"*
rmdir "$tmp"

修正する

実際にはpaxより良いアプローチになります。

pax -rws '/^ABC/DEF/' ABC.* .

残念ながら、これpaxはPOSIXおよびLinuxの標準ライブラリですが、現在はデフォルトでそれを含むディストリビューションはほとんどありません。

答え3

tarとても早くこれをやってくれます。

テスト

まず、2つのディレクトリと10のファイルを作成しました。

% mkdir test1 test2 ; cd test1
% for n in `seq 1 10` ; do touch ABC.file$n ; done
% ls

> ABC.file1   ABC.file2  ABC.file4  ABC.file6  ABC.file8
> ABC.file10  ABC.file3  ABC.file5  ABC.file7  ABC.file9

それからコピーしました。

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC/DEF/' -xf -
% ls ../test2

> DEF.file1   DEF.file2  DEF.file4  DEF.file6  DEF.file8
> DEF.file10  DEF.file3  DEF.file5  DEF.file7  DEF.file9

切り替える

したがって、GNUはファイルの名前変更をtar許可します。sed --transform=EXPRESSION特定のファイルの名前のみを変更することもできます。たとえば、

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC\(.*[0-5]\)/DEF\1/' -xf -
% ls ../test2

> ABC.file6  ABC.file8  DEF.file1   DEF.file2  DEF.file4
> ABC.file7  ABC.file9  DEF.file10  DEF.file3  DEF.file5

これが利点です。

小川

また、これは2つのtarプロセスにすぎず、保持しているファイルの数に関係なく変更されないことも考慮してください。

tar | tar

tar必要に応じて最適化してください。これにより、パラメータ計算の問題や暴走サブプロセスは発生しません。これだけA>B完璧。

議論

tarここでは、2つのプロセス間で結合された7つの異なるパラメータを使用しています。最も重要なことはここに最初にリストされています。

-標準出力/標準入力- これは、tar入力または出力をストリーミングすることを示します。stdin/stdoutアーカイブが構築されているか抽出されているかに応じて正しく解釈されます。

-c作る-tarプロファイルを作成するように求められます。次のパラメータは次tarのとおりです。

-f文書- テープデバイスまたは他のデバイスの代わりにオブジェクトをtar使用するように指定します。file前述のように、使用するファイルは次のとおりです。stdin/stdout- つまり、私たちの|pipe

./*すべての$PWD/ファイル- ここでは、アーカイブパラメータが最初に来る点を除き、特に説明は-ありません./*

|pipe...そして反対側に

-Cディレクトリの変更- これは、tar他のタスクを実行する前に私が指定したディレクトリに変更する必要があることを意味するので、cd ../test2解凍する前に機能します。

--transform='s/ed/EXPR/'- すでに述べたように、これで名前変更が完了します。しかし、ドキュメントには任意の式sed//flag

-xタブレット-tar宛先ディレクトリを変更して名前変更コマンドを受信した後、アーカイブ内のすべてのファイルを現在のディレクトリに抽出し始めるように指示します-f - |pipe。それについて不思議なことはありません。

答え4

zshで次の行を次の行に入力します.zshrc

autoload -U zmv
alias zmv='noglob zmv'
alias zcp='zmv -C'
alias zln='zmv -L'

次に、コマンドラインで次の操作を行います。君は走れるよ

zcp 'ABC(.*)' 'DEF$1'

または単に

zcp -W ABC.* DEF.*

他のシェルでは、zshがインストールされている限り:

zsh -c 'autoload zmv; noglob zmv -CW ABC.* DEF.*'

関連情報