ABC。*の中に多数のファイルが入ったフォルダーがあります(そのようなファイルは約100個あります)。それらをすべてDEF。*で始まる名前の新しいファイルに複製したい
だから、私は欲しい
ABC.Page1
ABC.Page2
ABC.Topic12
...etc
にコピー
DEF.Page1
DEF.Page2
DEF.Topic12
...etc
(BASHまたは類似の)バッチコマンドでこれを行う最も簡単な方法は何ですか? sed、awk、またはxargsを含むことを考えていますが、構文を理解するのが困難です。 Pythonスクリプトを記述できますが、複雑すぎないコマンドラインソリューションがあると思います。
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
多数のファイルでこれを効率的に行うには、ファイルごとに異なるcp
プロセスを開始しないことをお勧めします。 1つの方法は、prename
を使用してそれらをコピーし、名前を変更することです(rename
は、Debianベースのディストリビューションでは、デフォルトでこれにシンボリックリンクされています)。これと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 Standard Baseの両方ですが、現在、デフォルトで含まれているディストリビューションはほとんどありません。
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
これが利点の1つです。
また、これは2つのtar
プロセスのみであり、ファイル数に関係なく変更されないことを考慮してください。
tar | tar
tar
は、思い通りに最適化されています。これは問題のある引数の数や暴走した子プロセスを持つことは決してありません。これはA> B完了です。
ここでは、2つのtar
プロセス間で7つの異なる引数を組み合わせて使用しています。最も重要なものが最初にここにリストされています:
-
stdout/stdin-これはtar
に、入力または出力をストリーミングすることを通知しますstdin/stdout
へのストリーミングまたはビルド中かどうかに応じて正しく解釈されますアーカイブを抽出します。
-c
create-これはtar
にアーカイブをビルドするように指示します。tar
が期待する次の引数は...
-f
file-tar
がテープデバイスなどではなくfile
オブジェクトで動作することを指定します。上記のように、このファイルで使用するファイルはstdin/stdout
です。つまり、|pipe
。です。
./*
all $ PWD/files-アーカイブ引数が最初に来ることを除いて、ここでは説明しすぎないので、-
、./*
。
...そして|pipe
の反対側...
-C
change directory-これは、他のアクションを実行する前に、指定したディレクトリに変更する必要があることをtar
に通知するので、抽出する前に、単にcd ../test2
にするだけです。
--transform='s/ed/EXPR/'
-すでに述べたように、これは名前の変更を行いました。しかし、ドキュメントは、それがsed
式または//flag
を取ることができることを示しています。
-x
extract-tar
がターゲットディレクトリに変更され、名前変更の指示を受け取った後、-f - |pipe
アーカイブファイルから現在のディレクトリにすべてのファイルを抽出するように指示します。謎はありません。
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.*'
あなたはこれを行うことができます:
for i in ABC.*; do cp {ABC,DEF}."${i#*.}"; done