公開日 2022-07-09 更新日 2023-04-24
例えば、このようにしたい。
Screenshot from 2022-07-01 22-14-47.png ⇩ dv220701_221447.png
jpgならファイル中にタグを作って作成日時を埋め込めますが、pngではできません。GUIでコピーや移動する場合にタイムスタンプをコントロールするのは難しいことです。ファイル名に日時を記録しておくのが確実です。
どこかにスクリーンショットの名前のルールの設定があるのかもしれなませんが、とりあえず、すでにあるファイル名をawkなどでスクリプトを作って変更しました。学んだことを記録しておきます。
結論を先にいうと次のうちどれか
awk -F'[ -]' ' 'か'-'をひとつずつ awk -F' |-' ' 'か'-'をひとつずつ(|は文字列を指定できる) awk -F' +|-' ' 'の連続か'-'のひとつのどちらか awk -F'[ -]+' ' 'か'-'の連続
If FS is a single character, fields are separated by that character. If FS is the null string, then each individual character becomes a separate field. Otherwise, FS is expected to be a full regular expression. In the special case that FS is a single space, fields are separated by runs of spaces and/or tabs and/or newlines.
'.'は正規表現では任意の文字だが、-F'.'や -F'[ .]'ではピリオドを意味する。
ファイル名にスペースを含むので、''で囲む必要がある。
\047$0\047
""ならば
\042$0\042
2022を22にするために22は直接文字を書きました。
$ ls |awk -F'-| ' '{printf "mv \047%s\047 dv22%s%s_%s%s%s\n",$0,$4,$5,$6,$7,$8}'>>zz
作られるzzの内容は
mv 'Screenshot from 2022-07-01 22-14-47.png' dv220701_221447.png mv 'Screenshot from 2022-07-01 22-17-54.png' dv220701_221754.png mv 'Screenshot from 2022-07-01 22-18-58.png' dv220701_221858.png mv 'Screenshot from 2022-07-01 22-19-02.png' dv220701_221902.png ....
これを使ってファイル名を書き換えるなら
$ . zz
タイムスタンプが変わらないようにするにはmvがよいのだが、コピーしてから元を消すということをやってしまうことも考えられる。確実なのは cp -a としておいて後で消すという方法だろう。これだとスクリプトができてから、コピー先を変更して日別に分けたりすることも可能になる。
$ ls *.png |awk -F'-| ' '{printf "cp -a \047%s\047 ../d0701sc/dv22%s%s_%s%s%s\n",$0,$4,$5,$6,$7,$8}'>zzz
作られるzzzの内容は
cp -a 'Screenshot from 2022-07-01 22-14-47.png' ../d0701sc/dv220701_221447.png cp -a 'Screenshot from 2022-07-01 22-17-54.png' ../d0701sc/dv220701_221754.png cp -a 'Screenshot from 2022-07-01 22-18-58.png' ../d0701sc/dv220701_221858.png ....
これを使ってファイル名を書き換えるなら
$ . zzz
GUIでコピーしていたのですでにタイムスタンプが更新されていました。せっかく cp -a を思い出したのに残念。
そこでタイムスタンプを変更します。まず現在のタイムスタンプは次のようになっています。
$ ls -l *.png |head -rwxrwxrwx 1 adachi adachi 54533 7月 6 16:54 dv220701_221447.png -rwxrwxrwx 1 adachi adachi 76244 7月 6 16:54 dv220701_221754.png -rwxrwxrwx 1 adachi adachi 79303 7月 6 16:54 dv220701_221858.png -rwxrwxrwx 1 adachi adachi 79907 7月 6 16:54 dv220701_221902.png -rwxrwxrwx 1 adachi adachi 134753 7月 6 16:54 dv220701_222025.png
rwxrwxrwxなのはNTFSの3.5インチポータブルHDDのファイルだから。
statを使って詳細がわかります。ls -l で出てくるのはModify:の部分です。
$ stat dv220701_221447.png File: dv220701_221447.png Size: 54533 Blocks: 107 IO Block: 4096 通常ファイル Device: 38h/56d Inode: 141 Links: 1 Access: (0777/-rwxrwxrwx) Uid: ( 1000/ adachi) Gid: ( 1000/ adachi) Access: 2022-07-06 16:54:38.000000000 +0900 Modify: 2022-07-06 16:54:34.000000000 +0900 Change: 2022-07-06 16:54:34.000000000 +0900 Birth: -
sshを使ってネットワーク内のPCにコピーする場合は、scpを使います。
Ubuntuだとfumita.localなどでLAN内のPCを指定できます。
cpとはオプションが異なります。
scp -p *.png fumita.local:/media/adachi/S1T/....
-r Recursively copy entire directories.
-p Preserves modification times, access times, and modes from the original file.
touchが使えます。
touch -t STAMP :STAMPの書式は [[CC]YY]MMDDhhmm[.ss] touch -d STRING :STRINGの書式はたとえば 2022-07-06 16:54:38
今回の場合、手持ちのファイルにある日時の書式から使えるものはないかと探ってみる。
#x(使えない) touch -d "2022-07-01 22-14-47" dv220701_221447.png #o(使える) touch -d "2022-07-01 22:14:47" dv220701_221447.png #x(使えない) touch -d "220701_221447" dv220701_221447.png #o(使える) touch -t "2207012214.47" dv220701_221447.png
zzの内容を再掲すると
mv 'Screenshot from 2022-07-01 22-14-47.png' dv220701_221447.png mv 'Screenshot from 2022-07-01 22-17-54.png' dv220701_221754.png mv 'Screenshot from 2022-07-01 22-18-58.png' dv220701_221858.png mv 'Screenshot from 2022-07-01 22-19-02.png' dv220701_221902.png ....
第一案
$ cat zz |awk -F'[- .]' '{printf "touch -d \047%s/%s/%s %s:%s:%s\047 %s.png\n",$4,$5,$6,$7,$8,$9, $11}'
つまり、
$1 $2_________ $3__ $4__ $5 $6 $7 $8 $9 $10_ $11____________ $12 mv 'Screenshot from 2022-07-01 22-14-47.png' dv220701_221447.png
第二案
$ cat zz |awk -F'-| |.png' '{printf "touch -d \047%s/%s/%s %s:%s:%s\047 %s.png\n",$4,$5,$6,$7,$8,$9, $11}'
今度は、
$1 $2_________ $3__ $4__ $5 $6 $7 $8 $9 X $11____________ mv 'Screenshot from 2022-07-01 22-14-47.png' dv220701_221447.png
正規表現で文字候補を表す[ ]内ではピリオドはただのピリオドですが、複数の文字列の候補を表す | を使う場合はピリオドは任意文字になりますのでうまく行かなくなります。そこでpngをつけてpngの前に任意の文字があるものとして'.png'を区切りとして使います。$10は書けないのでXに変えていますが、これはシングルクォートになります。
どちらにしても、端末に出力されますから、うまく行くようになったら末尾に >zz2 などと適当なファイルに書き出して、
$ . zz2
としてスクリプトを実行します。
zz2は以下のような内容になります。
touch -d '2022/07/01 22:14:47' dv220701_221447.png touch -d '2022/07/01 22:17:54' dv220701_221754.png touch -d '2022/07/01 22:18:58' dv220701_221858.png ....
$ stat dv220703_173324.png File: dv220703_173324.png Size: 112534 Blocks: 224 IO Block: 4096 通常ファイル Device: 805h/2053d Inode: 5017960 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1000/ adachi) Gid: ( 1000/ adachi) Access: 2022-07-06 19:38:43.797390857 +0900 Modify: 2022-07-03 17:33:24.000000000 +0900 Change: 2022-07-06 19:29:47.711476015 +0900 Birth: -