瞬間日記をiPodを購入した2010年から使ってきたが、day oneが人気なので使ってみた。なかなかよかった。コマンドライン(CLI:Command Line Interface)から入力できるし、クラウドで同期できるのもいい。見た目もきれい。安定しているのもいい。
という訳で、瞬間日記からday oneにデータを引っ越しすることにした。
(このページで半角の>と表示されたら半角の”>”記号だと思ってください。HTMLの仕様のインプリバグでしょう。)
特定の日記アプリ間のデータの移動とは人生で一回しかないだろうから汎用性など考えずに間違えないように慎重にすることが大切だ。確かめて確かめて。このページはそんな備忘録である。また、瞬間日記のデータをday oneに移動させたという記事も見つけられなかったので誰かのお役に立てるかもしれない。でも自己責任でね。
瞬間日記は独自フォーマット(.dat3)や標準的な(.sqlite)、(.csv)でもMacにバックアップできる。使い勝手のいいcsvファイルは本文だけで写真情報が欠落している。瞬間日記のデータを引き上げるのは色々試したが、テキストばかりでなく写真も移動させたいの結局メールでバックアップすることにした。瞬間日記側で自分にひと月毎のバックアップをメールする。3年半分。ソチオリンピック開会式を見ながら作業でもれなく終了。
これは瞬間日記が30枚しか1つのメールに写真を貼付できないので、ひと月分だけせっせとメールする。
届いたメールはOSX側のmail.appで開くが、~/Libraryに保存されているelmsでなく、単にテキストファイルでmail.app側の機能を使って出力することにする。
瞬間日記のデータを取り出し、day oneにエントリできるくらいの粒度のファイルにするまでの流れ:
という訳で、瞬間日記からday oneにデータを引っ越しすることにした。
(このページで半角の>と表示されたら半角の”>”記号だと思ってください。HTMLの仕様のインプリバグでしょう。)
特定の日記アプリ間のデータの移動とは人生で一回しかないだろうから汎用性など考えずに間違えないように慎重にすることが大切だ。確かめて確かめて。このページはそんな備忘録である。また、瞬間日記のデータをday oneに移動させたという記事も見つけられなかったので誰かのお役に立てるかもしれない。でも自己責任でね。
瞬間日記は独自フォーマット(.dat3)や標準的な(.sqlite)、(.csv)でもMacにバックアップできる。使い勝手のいいcsvファイルは本文だけで写真情報が欠落している。瞬間日記のデータを引き上げるのは色々試したが、テキストばかりでなく写真も移動させたいの結局メールでバックアップすることにした。瞬間日記側で自分にひと月毎のバックアップをメールする。3年半分。ソチオリンピック開会式を見ながら作業でもれなく終了。
これは瞬間日記が30枚しか1つのメールに写真を貼付できないので、ひと月分だけせっせとメールする。
届いたメールはOSX側のmail.appで開くが、~/Libraryに保存されているelmsでなく、単にテキストファイルでmail.app側の機能を使って出力することにする。
瞬間日記のデータを取り出し、day oneにエントリできるくらいの粒度のファイルにするまでの流れ:
- iPodの瞬間日記のひと月分に区切ったバックアップデータを自分のメールアドレスに送信する
- OSXのmail.appで受信したメール全部(件名"MomentDialy"で始まるメールを一つのメールボックスに束ねる。例えばMomentDiaryというメールボックスに全部入れる
- mail.app上のメールボックスMomentDiary内の全部のメールを選択する。つまり⌘+a。
- mail.app上でファイル > 別名で保存 > 標準テキストを選択 し保存する。場所は適当(例えば~/Desktop)、添付ファイルを含めるはチェックしない。この例では"MomentDiary 2010年5月30日.txt"がファイル名になっている。
- 本当に全部の日記(エントリ)が保存されているのかの確認する。これは瞬間日記は日付を示す行の最初の文字が"-"なので次のコマンドで日付だけ表示できそうだ。
- Terminalで日付の確認$ awk '/^-/{print $0}' MomentDiary_\ 2010年5月30日.txt |more確かに狙い通りの日付がありそうだ。
- Terminal上で画像数の確認$ awk '/^# image/{print $0}' MomentDiary_\ 2010年5月30日.txt |sort |more
- 上のmoreをwcに置き換えると445と出たので画像は445枚あることがわかる
- Finder上で画像の確認する。そのためにメールボックスの画像データを移動する
- Finder上で「フォルダに移動⌘+SHIFT+G」で "~/Library"と入力し、Mailのデータを見る。
- Terminalでとりあえずメール情報全部をファイルをDesktop上にコピー。これは先ほどMail.appで束ねたメールボックスに対応しているフォルダだ。$ cp -r ~/Library/Mail/V2/Mailboxes/MomentDiary.mbox/ ~/Desktop/
- この~/Desktopにコピーしたフォルダの画像を検索する。画像ファイルは添付ファイルなのでそこ(/Attachments)まで移動する。このフォルダもまだまだ深いので画像ファイルをfindで検索する。画像名に重なりが無いかを調べる。
- $ cd ~/Desktop/2B5AF77B-14B3-4147-9C7D-CFB46B5318EF/Data/Attachments$ find . -iname "*.jpg" |awk 'BEGIN{FS="/"} {print $4}'
- findの結果はフォルダ名もついているのですぐにはわからない。画像ファイルのみを抽出するためにawkを使った。もっとスマートな方法あるかもしれないけどすぐ思いつく方法でためしたのだ。
- これに|wcを追加すると画像ファイル数を検出できる。おっと452個だ。メールの標準テキストで出力したファイルからの画像数は445個だったから7つ多い。あわない。それの理由を探してみる。まずmail.appから出力したテキストファイルから画像情報をファイル"ImageFileText.txt"に書き出し
awk '/^# image/{print $3}' ~/Desktop/MomentDiary_\ 2010年5月30日.txt |sort > ~/Desktop/ImageFileText.txt - 次に実在の画像ファイルをテキスト(ImageFileExist.txt)にまとめる
find . -iname "*.jpg" |awk 'BEGIN{FS="/"} {print $4}'|sort > ~/Desktop/ImageFileExist.txt - この二つをdiffで比較する
$ cd ~/Desktop$ diff ImageFileExist.txt ImageFileText.txt 280,286d279> 2346-m.jpg> 2346-m.jpg> 2346-m.jpg> 2346-m.jpg> 2346-m.jpg> 2346-m.jpg> 2346-m.jpg -
なるほど同じファイルが7個あるのか。で、画像ファイルを一つのフォルダに集める。念のため同じ名前がないか確認しておく。次のコマンドで確かに2346-m.jpgが8個ある。
$ uniq -c ~/Desktop/ImageFileExist.txt |sort $ find ~/Desktop/2B5AF77B-14B3-4147-9C7D-CFB46B5318EF/Data/ -name 2346-m.jpg -ls - 同じファイルサイズだから同じなのだろう。ここでfind の-lsオプションはlsと同じように出力している。
- 次に画像ファイルを~/Desktop/Imagesに集める
$ mkdir ~/Desktop/Images$ cd ~/Desktop/2B5AF77B-14B3-4147-9C7D-CFB46B5318EF/Data/Attachments/$ find . -iname "*.jpg" -exec cp {} ~/Desktop/Images/ \; - ここでフォルダ~/Desktop/Imagesに全部集まっているはず
$ ls ~/Desktop/Images/ |wc - 確かに上のコマンドで445枚のファイルになっている。
ここまでで、瞬間日記の標準テキストで出力された本文ファイル(MomentDiary 2010年5月30日.txt)一つと、画像ファイル445個を取り出すことが出来た。
さいよいよday oneの個別の登録ファイルの作成だ
- どうもこのファイル(MomentDiary 2010年5月30日.txt)は^L(改ページ)のコードが埋め込まれているようだ。そこでこのコードを取る。次のコマンドはsed -e 's/ の後にコントロールキーCtrlを押しながらvを押し(これをCtrl+vと表記)、その後にCtrl+lを押して入力している。UNIX使いの技だ。
$ sed -e 's/^L//' MomentDiary_\ 2010年5月30日.txt > MomentDiary.txt #改ページ(^L)のとれた本文ファイル - 次にメール送信にかかるコメント行を削除する。
$ sed -e '/差出人/d' -e '/件名/d' -e '/日付/d' -e '/宛先/d' -e '/iPadから送信/d' MomentDiary.txt > PlanMomentDiary.txt #メール送信情報が削除されたプレーンな本文ファイル - 念のため同じ日記があるか調べてみる
$ awk '/^-/{print $0}' MomentDiary_\ 2010年5月30日.txt |wc 2259 9036 77930$ awk '/^-/{print $0}' MomentDiary.txt|wc 2259 9036 77930$ awk '/^-/{print $0}' PlanMomentDiary.txt |wc 2259 9036 77930メール出力の本文ファイル(MomentDialy_ 2010年5月30日.txt)も、改ページコードを取った本文ファイル(MomentDialy.txt)も、メールヘッダを取ったプレーンな本文ファイル(PlanMomentDialy.txt)も同じエントリ数だ。よかった。ここまではOK。 - 次に日時が重なっている日記(エントリ)がないかを調べる。
$ awk '/^-/{gsub("-","",$0);gsub(" ","",$0);print $0 ".txt"}' MomentDiary.txt |sort > chech01.txt$ uniq -c chech01.txt |sort - このuniqコマンドは同じ行が幾つあるかも教えてくれる。2以上なら同じエントリがあるのだ。やっぱりあった。これらを別のエントリとするために片方の時間をちょっとずつ変えた。瞬間日記はcurrent timeを入れないと0:00となるので同じ日に2つ追加すると同じ日付と同じ時間になってしまうことが原因だろう。
- 次は各日記エントリー毎にファイルに分割するのだ。でもday oneのコマンドラインで自動で入力したいので次のようなコマンドを想定してファイル分割する。画像も指定する。これはday oneのCLIのexampleからの引用。
./dayone -d="25/03/2011 5:30PM" -s=true new < ~/Desktop/note.txt - 次にPlaneMomentDialy.txtから日記毎のファイルに分割する。
- awkは便利なもので、FSとRSをうまく使い分けると一つずつのエントリに区切ることができる。考え方は時間を指示している場所をRSとして、改行("¥n")をFSにすることで、改行情報を保ったまま複数ファイルに分割できるはずだ。
- でも途中に"-"があるとうまくいかないのでユニークな区切り記号として文字列"$#"に変えておく。このファイルに"$#"が無いことは確かめた。ただし"$"が一カ所だけあってうまく動かなかったので"$"と全角に変えて区切り文字とは区別させた。また、-------------------------という行があったのでその行は削除した。このあたりはviで手作業となるが、一回だけなのでOKとした。
- $ awk '/^-/{gsub("-","$#")}{print $0;}' PlanMomentDialy.txt > OutPut.txt
- 次のプログラムを作って$ vi MomentDialy2DayOne.awk
1 #!/usr/bin/awk -f2 # 瞬間日記からday oneへインストールするためのファイル切り出しコマンド3 BEGIN{4 RS="$#"5 FS="\n"6 fn=""7 print ARGV[1]8 getline #一行目をスキップする9 }1011 {12 gsub("#","",$1)13 date="# date:" $1 # 日時を保存しておく14 gsub(" ","",$1)15 fn=$1 ".txt" #ファイル名の生成16 printf("%s\n",fn) #画面上にファイル名の表示17 $1=date18 for(i=1;i<=NF;i++)19 { print $i> fn} #複数ファイルに分割20 close(fn) #複数ファイルを扱うとき、一回一回は閉じなければいけない21 }
$ ./MomentDialy2DayOne.awk OutPut.txt
ls -f 2*|sort > chech02.txtawkでファイルに分割した。2257個のファイルができた。差が2つあるが、これは途中でaiffの音声データのファイルもあったものをviで消したもので数字はあっている。
さて、これで大方仕事は終わった。後は注意深く日時、画像データを取り出してday one に喰わせればいい。夜も更けたので今日はここまで。
画像ファイルを移動しておく。
Mac側でday oneを見ると確かに狙い通りに出来ている。あまりかっこ良くないけどこんなスクリプトを書いてみた。awkの実装するindex()関数の日本語の文字位置検出に不安があるので英文字に変換している。また画像のファイルも指定してある。CLIでのday oneのエントリはオプションを必ずnewの前につけるのが大切だ。
ま、望みのものは出来たのでよしとする。
これをbashのfor文を用いてコマンド化する。
一気に行わずに少しずつ試すのがいい。いよいよエントリの登録である。
day oneは同じエントリを複数回行うと、複数個のエントリが可能である。つまり同じエントリが出来てしまう。瞬間日記ではリストアでは重なりがあっても一つになっていたが。
もし、間違えてしまったらday oneの出力結果からdoentryファイルを単に消すだけでいいみたいだ。
というわけで、ログを取っておくのがいい。
以上で2000件以上を登録することができた。
これで瞬間日記のデータをday oneに移すことが出来た。週末1.5日の仕事。錆び付いた頭のUNIXを思い出し思い出しsed, awk, grep, uniq、bashという古典的なコマンド群達はきちんと働いてくれた。もちろんRuby、Pythonはもっと効率がいいだろうけど、こんな方法でやりたいことが出来ればそれはそれでたのしいのだ。移動作業は一回こっきりしかしないのだし。
(追加:データの整理)
登録したエントリにタグ#date と# imageがうっとうしく感じてこれを取ることにした。
スクリプトは簡単なのと途中記録がブレーカオフで消えたのでここでは書かないが、注意点として、iPodやiPadのデータはそのままでは更新されなかった。仕組みがまだ分からないが、アプリを消して再登録するとiCloudからデータをダウンロードを始める。多分大丈夫でしょう。
まず確認
次にいよいよday oneに日記データの移動。まず一つだけ手作業で行ってみた。画像ファイルを移動しておく。
$ mv ~/Desktop/Images/ ~/Desktop/Entry/
$ dayone -d="12/05/2013 17:50" -p=Images/2272-m.jpg new < 2013年12月5日木曜日17\:50.txt
Mac側でday oneを見ると確かに狙い通りに出来ている。あまりかっこ良くないけどこんなスクリプトを書いてみた。awkの実装するindex()関数の日本語の文字位置検出に不安があるので英文字に変換している。また画像のファイルも指定してある。CLIでのday oneのエントリはオプションを必ずnewの前につけるのが大切だ。
$ GetDate.awk
1 #!/usr/bin/awk -f
2 # 瞬間日記からday oneへ時間を切り出すスクリプト
3 # usage ./GetDate.awk 2013年12月5日木曜日17\:50.txt
4 BEGIN{
5 FS=" "
6 printf( "%s", "dayone ")
7 }
8
9 /^# date:/{
10 jdate=$3
11 time=$5
12 # print jdate
13 gsub("年", "y", jdate)
14 gsub("月", "m", jdate)
15 gsub("日", "d", jdate)
16 # print jdate
17 ny= index(jdate,"y")
18 # print "ny=" ny
19 nm= index(jdate,"m")
20 # print "nm=" nm
21 nd= index(jdate,"d")
22 # print "nd=" nd
23 year = substr(jdate,1,ny-1)
24 month = substr(jdate,ny+1,nm-ny-1)
25 date = substr(jdate,nm+1,nd-nm-1)
26 printf(" -d=\"%s/%s/%s %s\"", month, date , year, time)
27 # print
28 }
29 /^# image:/{
30 image=$3
31 printf(" -p=\"./Images/%s\" ",image)
32 }
33 END{
34 printf( " new < %s \n",ARGV[1])
35 }
これをbashのfor文を用いてコマンド化する。
$ for file in 2013年12月29日*.txt ; do ./GetDate.awk $file; done > cmd20131229.sh
一気に行わずに少しずつ試すのがいい。いよいよエントリの登録である。
$ sh cmd2013.sh
New entry : ~/Library/Mobile Documents/5U8NS4GX82~com~dayoneapp~dayone/Documents/Journal_dayone/entries/9981CDBA1A314A4BBC270C23CB605B08.doentry
もし、間違えてしまったらday oneの出力結果からdoentryファイルを単に消すだけでいいみたいだ。
$ rm ~/Library/Mobile¥ Documents/5U8NS4GX82~com~dayoneapp~dayone/Documents/Journal_dayone/entries/9981CDBA1A314A4BBC270C23CB605B08.doentry
$ touch LogAttendEntries2010.log
$ for file in 2010年*.txt ; do ./GetDate.awk $file; done > cmd2010.sh
$ sh cmd2010.sh >> LogAttendEntries2010.log
以上で2000件以上を登録することができた。
これで瞬間日記のデータをday oneに移すことが出来た。週末1.5日の仕事。錆び付いた頭のUNIXを思い出し思い出しsed, awk, grep, uniq、bashという古典的なコマンド群達はきちんと働いてくれた。もちろんRuby、Pythonはもっと効率がいいだろうけど、こんな方法でやりたいことが出来ればそれはそれでたのしいのだ。移動作業は一回こっきりしかしないのだし。
(追加:データの整理)
登録したエントリにタグ#date と# imageがうっとうしく感じてこれを取ることにした。
スクリプトは簡単なのと途中記録がブレーカオフで消えたのでここでは書かないが、注意点として、iPodやiPadのデータはそのままでは更新されなかった。仕組みがまだ分からないが、アプリを消して再登録するとiCloudからデータをダウンロードを始める。多分大丈夫でしょう。
コメント