cpコマンドでデータのコピー先を一度に複数指定する方法
cpコマンドでデータのコピーを行う場合、通常はコピー先は1つになります。
ですが、複数のコピー先を「xargs」コマンドに渡してcpコマンドを使用すると、一度にコピー先を複数指定することができます。
複数のコピー先を「xargs」コマンドに渡す方法として、今回はbashの機能つかった3通りを紹介していきます。
- ・ブレース展開を使用
- echo {コピー先1,コピー先2} | xargs -t cp -p コピー元
- ・forを使用
- for i in コピー先1 コピー先2; do echo $i; done | xargs -t -n 1 cp -p コピー元
- ・whileを使用(ファイルから読み込み)
- while read line; do echo "$line"; done < "ファイル" | xargs -t -n 1 cp -p コピー元
今回紹介する方法でデータのコピーを行う場合は、誤ったコピー先をxargsに渡してしまわないか事前に問題ないデータでコピーのテストを行うことをおすすめします。
xargsのオプション
xargsコマンドで使用しているオプションの説明です。
- -t 実行するとコマンドと引数を表示
- -n 1 xargsに渡す引数の最大数を1として指定
-t オプション
「-t」オプションを指定すると「cp -p コピー元 コピー先」といったように、実行した内容が表示されます。
実行した内容を表示させる必要がなければ必要はありません。
-n 1 オプション
「-n 1」でxargsに渡す引数の最大数を1つに指定しないと、「コピー先1 コピー先2」がまとめてxargsに渡されてしまいます。
コピー先として「test_dir1」と「test_dir2」を指定して「-n 1」オプションを使わずコピーを実行してみます。
$ echo {test_dir1,test_dir2} | xargs -t cp -p test.txt
cp -p test.txt test_dir1 test_dir2
cp: -r not specified; omitting directory 'test_dir1'
cp -p test.txt test_dir1 test_dir2と表示されているように、「test_dir1 test_dir2」が一度にxargsに渡されてしまいコピーが失敗しています。
bashのブレース展開を使用
bashのブレース展開使い、複数のコピー先をxargsコマンドに渡す方法です。
echo {コピー先1,コピー先2} | xargs -t cp -p コピー元
コピー先を増やす場合は、「,」で区切って「echo {コピー先1,コピー先2,コピー先3} 」といったようにコピー先を追加します。
実行例
テスト用として、下記のような「test.txt」ファイルと「test_dir1」「test_dir2」というディレクトリを用意しました。
$ ls -lR .: total 12 -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt drwx------ 2 tamohiko tamohiko 4096 Apr 10 00:18 test_dir1 drwxrwxr-x 2 tamohiko tamohiko 4096 Apr 10 00:18 test_dir2 ./test_dir1: total 0 ./test_dir2: total 0
ブレース展開を使用して「test_dir1」と「test_dir2」を「xargs」に渡して、「test.txt」ファイルをコピーします。
下記の例は「text.txt」が「test_dir1」と「test_dir2」ディレクトリにコピーされます。
$ echo {test_dir1,test_dir2} | xargs -t -n 1 cp -p test.txt cp -p test.txt test_dir1 cp -p test.txt test_dir2
「test_dir1」と「test_die2」ディレクトリに「test.txt」ファイルがコピーされていることを確認します。
$ ls -lR .: total 12 -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt drwx------ 2 tamohiko tamohiko 4096 Apr 10 00:21 test_dir1 drwxrwxr-x 2 tamohiko tamohiko 4096 Apr 10 00:21 test_dir2 ./test_dir1: total 4 -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt ./test_dir2: total 4 -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt
こんな書き方もできます。
$ echo test_dir{1,2} | xargs -t -n 1 cp -p test.txt cp -p test.txt test_dir1 cp -p test.txt test_dir2
forを使用する方法
bashのforを使用して複数のコピー先をxargsに渡す方法も有ります。
for i in コピー先1 コピー先2; do echo $i; done | xargs -t -n 1 cp -p コピー元
コピー先を増やしたい場合は、スペースで区切って「for i in コピー先1 コピー先2 コピー先3;」といったようにコピー先を追加します。
実行例
forを使用して「test_dir1」と「test_dir2」を「xargs」に渡して、「test.txt」ファイルをコピーします。
$ for i in test_dir1 test_dir2; do echo $i; done | xargs -t -n 1 cp -p test.txt cp -p test.txt test_dir1 cp -p test.txt test_dir2
whileを使う方法
bashのwhileを使うとバックアップ先を記述したファイルから読み込んで、コピー先を指定することもできます。
$ while read line; do echo "$line"; done < "ファイル" | xargs -t -n 1 cp -p コピー元
実行例
「backup_list.txt」というバックアップ先を記述したファイルを事前に作成しました。
$ cat backup_list.txt ./test_2.txt ./test_dir1/test.txt ./test_dir2/test.txt
「backup_list.txt」ファイルを読み込んで「text.txt」をコピーします。
$ while read line; do echo "$line"; done < "./backup_list.txt" | xargs -t -n 1 cp -p test.txt cp -p test.txt ./test_2.txt cp -p test.txt ./test_dir1/test.txt cp -p test.txt ./test_dir2/test.txt
実際に「test.txt」がコピーされていることが確認できます。
$ ls -Rl .: total 20 -rw-rw-r-- 1 tamohiko tamohiko 55 Apr 10 14:42 backup_list.txt -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test_2.txt drwx------ 2 tamohiko tamohiko 4096 Apr 10 14:45 test_dir1 drwxrwxr-x 2 tamohiko tamohiko 4096 Apr 10 14:45 test_dir2 ./test_dir1: total 4 -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt ./test_dir2: total 4 -rw-rw-r-- 1 tamohiko tamohiko 5 Apr 9 11:15 test.txt
日時をつけてコピーする方法
設定ファイルをコピーしてバックアップを行う場合、コピー先のデータに日時を追加してコピーしたいことがあると思いますので、コピー先に日時を追加する方法も紹介します。
ブレース展開を使用
下記の例だと、コピーした日時をつけたtest.txtを同じフォルダ内とtest_dir2ディレクトリの2箇所にコピーしています。
$ echo {test.txt_$(date +%Y%m%d-%H%M%S),test_dir2/test.txt_$(date +%Y%m%d-%H%M%S)} | xargs -t -n 1 cp -p test.txt cp -p test.txt test.txt_20240409-112731 cp -p test.txt test_dir2/test.txt_20240409-112731
forを使用した場合
forを使用する場合はこんな感じになります。
$ for i in test.txt_$(date +%Y%m%d-%H%M%S) test_dir2/test.txt_$(date +%Y%m%d-%H%M%S); do echo $i; done | xargs -t -n 1 cp -p test.txt cp -p test.txt test.txt_20240409-114024 cp -p test.txt test_dir2/test.txt_20240409-114024
whileを使用した場合
whileを使用して、バックアップ先をファイルから読み込む場合はこんな感じになります。
$ while read line; do echo "$line"_$(date +%Y%m%d-%H%M%S); done < "./backup_list.txt" | xargs -t -n 1 cp -p test.txt cp -p test.txt ./test_2.txt_20240410-145705 cp -p test.txt ./test_dir1/test.txt_20240410-145705 cp -p test.txt ./test_dir2/test.txt_20240410-145705
コメント