macでxcopy /dの代替（特定の日付以降に更新されたファイルだけcp）

# なにこれ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【ゆる募】Macユーザの人教えて下さい<br>(1)Windowsのcmdでできるxcopy -d、どうやってやるの？（ソフト利用でもOK）<br>(2)WinMergeに変わるソフト（フォルダ比較、ファイル比較）<br>(3)正規表現置換ができる軽めのソフト（現在sakuraエディタ）<br>(4)FTPソフト（現在WinSCP、マスクかけてミラーリングしたい）</p>&mdash; なー (@vful) <a href="https://twitter.com/vful/status/1101289788030672896?ref_src=twsrc%5Etfw">2019年3月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ということで(1)のみ試してみた。

# 実際にやってみる
## まずは調べる
Windowsでターミナルを叩くことがなかったので調べてみた。
FYI: https://jj-blues.com/cms/command-xcopy/

> 日付が新しいファイルのみコピーする

ふむふむ。
今まであまり考えたことなかったけど、便利だね。

## `xcopy /d` の代替
### テスト環境
こんな環境を想定する。
* ディレクトリが2つ　　 : `old`と`new`
* 片方だけファイルが多い : `old/b.txt`
のとき、`old/b.txt`のみが`new`にコピーされればOK。

```
$ ls -Rla
total 0
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:31 .
drwxr-xr-x  12 maruta-hirokazu  staff  384  3  1 12:39 ..
drwxr-xr-x   3 maruta-hirokazu  staff   96  3  1 14:37 new
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:31 old

./new:
total 8
drwxr-xr-x  3 maruta-hirokazu  staff   96  3  1 14:37 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--  1 maruta-hirokazu  staff   15  3  1 14:36 a.txt

./old:
total 16
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--@ 1 maruta-hirokazu  staff   51  3  1 14:30 a.txt
-rw-r--r--@ 1 maruta-hirokazu  staff   12  3  1 14:31 b.txt
$ cat ./new/a.txt
hoge
fuga
piyo
$ cat ./old/a.txt
(^^;)
(꜆꜄꜆˙꒳˙)꜆꜄꜆
(「・ω・)「
$ cat ./old/b.txt
aaa
bbb
ccc
$ diff new/a.txt old/a.txt
1,3c1,3
< hoge
< fuga
< piyo
---
> (^^;)
> (꜆꜄꜆˙꒳˙)꜆꜄꜆
> (「・ω・)「
```

### コマンド
`cp -r -n <コピー元ディレクトリ名>/* <コピー先ディレクトリ名>`

* `-r`: 再帰的にコピー
* `-n`: 重複があった場合は無視する

余談: linuxの場合は`--parents`みたいなイカしたオプションがあるんだけどなぁ・・・

### 実行結果
```
$ cp -r -n old/* new
$ ls -Rla
total 0
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:31 .
drwxr-xr-x  12 maruta-hirokazu  staff  384  3  1 12:39 ..
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:42 new
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:31 old

./new:
total 16
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:42 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--  1 maruta-hirokazu  staff   15  3  1 14:36 a.txt
-rw-r--r--@ 1 maruta-hirokazu  staff   12  3  1 14:42 b.txt

./old:
total 16
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--@ 1 maruta-hirokazu  staff   51  3  1 14:30 a.txt
-rw-r--r--@ 1 maruta-hirokazu  staff   12  3  1 14:31 b.txt
$ diff new/a.txt old/a.txt
1,3c1,3
< hoge
< fuga
< piyo
---
> (^^;)
> (꜆꜄꜆˙꒳˙)꜆꜄꜆
> (「・ω・)「
$ diff new/b.txt old/b.txt
```
無事コピー完了。

余談だけど`cp -r old/* new`にしちゃうと容赦無く上書きされるから注意。

## 発展：指定した日付以降のファイルのみコピー
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ほぉー。-nって調べて全然でてこなくてどんづまったけど、-iのNoバージョンなんだね。<br>-bでバックアップ取りながらコピーしたり、タイムスタンプ確認したり、macのcp優秀。<br>例えばなんだけど、yyyy-mm-dd以降に更新したものだけcpとかってできたりする？</p>&mdash; なー (@vful) <a href="https://twitter.com/vful/status/1101333245986127872?ref_src=twsrc%5Etfw">2019年3月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ほ・・・ほほう・・・。
確かに気になるね。


ということでやってみた

### テスト環境
`古いファイル`を作成。

```
$ touch -t "201001010000" old/c.txt
$ touch -t "201101010000" old/d.txt
```

こいつらはコピー対象外

```
$ ls -Rla
total 0
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:31 .
drwxr-xr-x  12 maruta-hirokazu  staff  384  3  1 12:39 ..
drwxr-xr-x   3 maruta-hirokazu  staff   96  3  1 14:54 new
drwxr-xr-x   6 maruta-hirokazu  staff  192  3  1 14:52 old

./new:
total 8
drwxr-xr-x  3 maruta-hirokazu  staff   96  3  1 14:54 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--  1 maruta-hirokazu  staff   15  3  1 14:36 a.txt

./old:
total 16
drwxr-xr-x  6 maruta-hirokazu  staff  192  3  1 14:52 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--@ 1 maruta-hirokazu  staff   51  3  1 14:30 a.txt
-rw-r--r--@ 1 maruta-hirokazu  staff   12  3  1 14:31 b.txt
-rw-r--r--  1 maruta-hirokazu  staff    0  1  1  2010 c.txt
-rw-r--r--  1 maruta-hirokazu  staff    0  1  1  2011 d.txt
```
これに対して、先ほどの**既に存在するファイル以外をコピー**する

### コマンド
`find <コピー元ディレクトリ名> -type f -newermt 'YYYY-MM-DD' |  xargs -J% cp -r -n % <コピー先ディレクトリ名>`


### 実行結果
* `2019-03-01`以降のファイルのみコピー
* ただし、既存のファイルはそのまま

```
$ find old -type f -newermt '2019-03-01' |  xargs -J% cp -r -n % new
$ ls -Rla
total 0
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:31 .
drwxr-xr-x  12 maruta-hirokazu  staff  384  3  1 12:39 ..
drwxr-xr-x   4 maruta-hirokazu  staff  128  3  1 14:55 new
drwxr-xr-x   6 maruta-hirokazu  staff  192  3  1 14:52 old

./new:
total 16
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:55 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--  1 maruta-hirokazu  staff   15  3  1 14:36 a.txt
-rw-r--r--@ 1 maruta-hirokazu  staff   12  3  1 14:55 b.txt

./old:
total 16
drwxr-xr-x  6 maruta-hirokazu  staff  192  3  1 14:52 .
drwxr-xr-x  4 maruta-hirokazu  staff  128  3  1 14:31 ..
-rw-r--r--@ 1 maruta-hirokazu  staff   51  3  1 14:30 a.txt
-rw-r--r--@ 1 maruta-hirokazu  staff   12  3  1 14:31 b.txt
-rw-r--r--  1 maruta-hirokazu  staff    0  1  1  2010 c.txt
-rw-r--r--  1 maruta-hirokazu  staff    0  1  1  2011 d.txt
$ diff new/a.txt old/a.txt
1,3c1,3
< hoge
< fuga
< piyo
---
> (^^;)
> (꜆꜄꜆˙꒳˙)꜆꜄꜆
> (「・ω・)「
$ diff new/b.txt old/b.txt
```

* 元々存在するファイルはコピーされていない
* 指定日より古いファイルはコピーされていない

### 解説
`find old -type f -newermt '2019-03-01'`

* oldの中身に対し検索
  * ただしファイルのみ（ディレクトリは無視）
  * タイムスタンプが'2019-03-01'以降のもののみを対象とする

* `xargs -J% cp -r -n % new`
  * `xargs -J%` で %を実行結果で置換
      * この場合「findによる検索結果のファイル名」それぞれが実行対象
  * cp以降は上で解説したコピーコマンドと同様

# 感想
思ったよりWindowsのコマンドが優秀。
shell芸バシバシやらないといけないことを考えると便利な感じはある。
~~まぁ使わないんだけど~~

`cp`とか`xargs`とか普段使っているけど特に振り替えれなかったコマンドについて考えられたので満足。
ありがとうなーさん。
ていうかタイムスタンプ的に仕事中に遊んでんのがバレちゃうマズイいまずい。