質問: コマンドラインmv除外リスト 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/ _