はじめに
これがQiita初投稿です。
エンジニアになって3年目、ずっとQiitaにお世話になってはいましたが、技術記事と言う形でOutputすることはできていませんでした。ただ、業務中にやってきた技術内容をNotionをまとめてきたので、これから頑張ってアップしていこうと思います。
やりたいこと
あるディレクトリに様々な拡張子ファイルが含まれており、これをコマンド一発叩くだけで別フォルダに移したい。
もちろんいろいろやり方はあるので複数例を提示する。
この方法を応用すれば、コピー以外にも他にもできることがある。
ユースケース
💡 特定のフォルダにはPythonスクリプトとjpgファイルが含まれている。このフォルダからjpgファイルだけを別フォルダにコピーしたい。やり方1:cpコマンド、findコマンドを使用
find /path/to/source/folder -maxdepth 1 -type f -name "*.jpg" -exec cp {} /path/to/destination/folder \;
-
find
:ファイル検索ユーティリティ。フォルダ内のファイルを検索する。 -
/path/to/source/folder
:検索するフォルダのパスを指定する。このパスには、スクリプトとjpgファイルが含まれているフォルダを指定します。 -
maxdepth 1
:フォルダ内のサブフォルダを検索しないようにする。つまり、検索は指定されたフォルダの直下のファイルに限定される。 -
type f
:ファイルの種類を指定する。この場合、ファイルのみを検索する。 -
name "*.jpg"
:検索するファイル名を指定する。この場合、拡張子が「.jpg」のファイルのみを検索する。 -
exec cp {} /path/to/destination/folder \;
:検索されたファイルに対して実行するコマンドを指定する。この場合、検索されたファイルを別のフォルダにコピーするために、**cp
**コマンドを使用する。{}
は、検索されたファイルの名前に置き換えられる。最後の\;
は、このオプションの終了を示す。
やり方2:rsyncコマンドを使用
個人的に、上記ユースケースではこれがお気に入り。
rsync -avz --include="*/" --include="*.jpg" --exclude="*" /path/to/source/folder/ /path/to/destination/folder/
-
rsync
:ファイルの同期を行うコマンド。今までリモート相手にしか、使用することないと考えていたが、ローカル内完結でも使うことができるとは! -
avz
:rsync
コマンドのオプションを3つ組み合わせたもの。-
a
:アーカイブモード。ファイル属性を保持してコピーする。 -
v
:詳細モード。ファイルのコピーを詳細に表示する。 -
z
:圧縮モード。ファイルを圧縮して転送する。
-
-
-include="*/"
:指定されたフォルダを含める。 -
-include="*.jpg"
:拡張子が「.jpg」のファイルを含める。 -
-exclude="*"
:上記の条件に当てはまらないすべてのファイルを除外。 -
/path/to/source/folder/
:コピー元のフォルダを指定する。最後にスラッシュ(/)が必要。 -
/path/to/destination/folder/
:コピー先のフォルダを指定する。最後にスラッシュ(/)が必要。
jpgファイルだけでなくjpegファイルも含めたいとき
以下のようにする。
- **
--include
**オプションで.jpg
と指定している箇所を.jpg
と*.jpeg
の両方に変更 - **
--exclude
**オプションを削除
rsync -avz --include="*/" --include="*.jpg" --include="*.jpeg" /path/to/source/folder/ /path/to/destination/folder/
やり方3:findコマンド、xargsコマンド、cpコマンドを使用
find /path/to/source/folder -maxdepth 1 -type f -name "*.jpg" | xargs -I{} cp {} /path/to/destination/folder
パイプ(|)前まではやり方1と同じなので割愛。
-
xargs
:標準入力からのデータを引数にしてコマンドを実行するために使用する。 -
-I{}
:**xargs
コマンドが入力の各行を引数に変換する際に、{}
というプレースホルダを使用することを指定する。このプレースホルダは、cp
**コマンドで使用されることになる。
おまけ:args
とxargs
**args**
は指定されたコマンドに引数リストを渡すために使われるが、**xargs
**は標準入力から引数文字列を受け取り、それを指定されたコマンドの引数として解釈される。
$ echo foo bar baz | xargs echo
foo bar baz
**echo foo bar baz
**コマンドが実行され、パイプラインで渡されたデータが標準入力から引数として渡される。
$ ls | xargs rm
**ls
コマンドで出力されたファイルリストをxargs
コマンドに渡し、rm
**コマンドに引数として渡している。