mv
、cp
、または影響を受けたくないすべてのファイルを指定できるようなファイル操作はありますか?
たとえば、ファイルfile1
、file2
、およびfile3
を含むフォルダーがあり、file1
およびfile2
をどこかに移動したいとします。移動するファイルに明示的に名前を付けるのではなく(mv file1 file2 /path/to/destination
)、移動するファイルに not という名前を付けて、フォルダー内の他のすべてのファイルを移動させます(mv --some-switch file3 /path/to/destination
)
一部のシェルで高度なグロブパターンを使用して、特定のパターンに一致するファイルを除く、ディレクトリ内のすべてのファイルに一致させることができます。たとえば、ksh、bash、またはzshでは、コマンド
_shopt -s extglob ## needed in bash only
setopt ksh_glob ## needed in zsh only
mv /source/!(*.bak) /destination
_
_/source
_に一致するファイルを除き、_/destination
_内のすべてのファイルを_*.bak
_に移動します。 zshでは、最初に_/source/^*.bak
_を実行した場合は、_setopt extended_glob
_を書き込むこともできます。より一般的には、(ここでも_setopt extended_glob
_が必要です)_/source/*~*.bak
_(または_/source/a*~*.bak
_ _.bak
_ファイルなどを除いて、名前はa
で始まります。
Zshには、特に、パターンに一致するファイルを除くすべてのファイルを移動するために使用できる一括コピー/移動/リンクコマンドがあります。たとえば、次のコマンドは、_*.bak
_を除くすべてのファイルを_/source
_からtarget
に移動し、プロセスで名前に_.bak
_を追加します。
_autoload zmv
zmv '/source/(*)~*.bak' '/target/$1.bak'
_
rename
と呼ばれるいくつかのコマンドが浮かんでいます。 DebianおよびUbuntuでは、_/usr/bin/rename
_は、Perl式によって生成された新しい名前にファイルを移動するPerlスクリプトです。ファイルを除外する場合は、新しい名前を生成しないことで、ファイルの名前変更から除外できます。たとえば、次のコマンド(この特定のrename
プログラムを使用)は、_*.bak
_を除くすべてのファイルを_/source
_から_/target
_に移動します。
_rename 's!/source!/target! unless m!\.bak$!' /source/*
_
find
コマンドを使用して、移動するファイルを選択できます。たとえば、次のコマンドは、_*.bak
_の_/source
_またはサブディレクトリを除くすべての通常のファイルを_/target
_に移動します(ディレクトリ構造が折りたたまれていることに注意してください)。
_find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
_
または(移動するファイルが多い場合はより効率的)
_find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
_
rsync
は、cp
とscp
を一般化したもので、非常に強力な包含/除外ルールがあります。たとえば、次のコマンドは、ディレクトリ構造を考慮して、_*.bak
_の_/source
_またはサブディレクトリを除くすべてのファイルを_/target
_にコピーします。
_rsync -a --exclude '*.bak' /source/ /target/
_
pax
は(とりわけ)ステロイドの別のcp
です。その除外ルールはrsyncほど強力ではありませんが、コピー時にファイルの名前を変更する追加機能があります。ファイルの名前を空の文字列に変更すると、そのファイルはコピーから除外されます。たとえば、次のコマンドは、_*.bak
_の_/source
_またはサブディレクトリを除くすべてのファイルを_/target
_にコピーし、ファイルの名前を_.bak
_に変更します。
_cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
_
上記の例には、_foo.bak
_というディレクトリを作成するという不幸な副作用があります。これは、find
とpax
を組み合わせることで回避できます。
_{ cd /source && find . -type f; } | \
pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
_