Apple の脅威の通知と金銭目当てのスパイウェアへの対策について

しばらく返答が寄せられていないようです。 再度ディスカッションを開始するには、新たに質問してください。

AppleScript 条件によりファイルの移動

ファイル名の中に"【"と"】"が含まれていて、そのファイルが存在する同階層内に、

"【"と"】"に囲まれたフォルダが存在した場合、目的のファイルを

そのフォルダに移動するスクリプトを作ろうと思ってます。

(注意)…"【"と"】"が含まれないファイルもあり


初歩的な質問ばかり毎回して申し訳ありません。

考えれば、多少なりともスクリプトを書けるのかもしれませんが、

また一週間以上悩んでしまいそうなので、丸投げの状態で聞いてしまってます。

本当に申し訳ありません。


具体的には、以下のようなイメージです。

"Macintosh HD:Users:UserName:Documents:"←ファイルが存在する階層

"Macintosh HD:Users:UserName:Documents:請求書:"←移動先のフォルダ

"【請求書】ABC.pdf"←対象となるファイル

(注意)…例えば"XYZ.pdf"のように"【"と"】"共に含まれない、もしくはどちらか一方しか入っていないファイルは移動対象外。

また"】領収書【DEF.pdf"のように"】"と"【"の順番が逆のファイルは存在しないと仮定。



目的を簡単に言えば、自動でフォルダへ整理整頓したいのです。

AppleScriptより上位のプログラムで移動すれば、

簡単なのですが、それをしてしまうと、移動先のフォルダが多くなった時、

例えば、請求書だけでなく、納品書、領収書などのフォルダにも移動したい場合に、

AppleScriptが汎用的でなくなってしまいます。

"【"と"】"の間の文字列で判断し、名前毎にファイルを移動したいと考えてますが、

"【"と"】"を使わなくても、他にいいアイデアがあば、それでも構いません。


毎回申し訳ありませんが、お知恵をお願いします。

Mac mini, Mac OS X (10.6.8)

投稿日 2013/08/01 17:26

返信
スレッドに付いたマーク ベストな回答

投稿日 2013/08/01 19:25

失礼致します。 "【"と"】"の間の文字列が決まっていれば、【】を含んだ文字列そのものをキーワードにすると簡単そうですが、如何でしょう? 例えば、【請求書】、【領収書】のように決まった文字列が【】の間に含まれるのであれば、【請求書】や【領収書】をそのまま検索文字列としてファイル名を検索するという方法であれば簡単そうですね。 しかし、【】内の文字列が任意であれば、ちょっと複雑そうです。

返信: 11
スレッドに付いたマーク ベストな回答

2013/08/01 19:25 へなちょこ への返信

失礼致します。 "【"と"】"の間の文字列が決まっていれば、【】を含んだ文字列そのものをキーワードにすると簡単そうですが、如何でしょう? 例えば、【請求書】、【領収書】のように決まった文字列が【】の間に含まれるのであれば、【請求書】や【領収書】をそのまま検索文字列としてファイル名を検索するという方法であれば簡単そうですね。 しかし、【】内の文字列が任意であれば、ちょっと複雑そうです。

2013/08/01 22:20 へなちょこ への返信

ファイル取得までとりあえず。


tellapplication"Finder"--フォルダを選択して実行


seta1toselectionasalias list


seta2tofilesofa1'sitem1asalias list

set a4 to {}


repeatwitha3ina2


if""isinnameofa3then


if""isinnameofa3thenseta4toa4 & a3


endif


endrepeat


loga4--""""が含まれるファイルのリスト

endtell


やっぱり丸投げに丸答えは後々へなちょこさんのスキルアップにつながらないので、

少し考えてみましょうね。

grepとかdo shell script を組み合わせればもっと簡単に行けますね。

2013/08/02 11:19 T22T への返信

いつもご指導ありがとうございます。

英語のマニュアルはちょっと・・・。

バカな私には読めません(涙;)


できれば、決められた文字列にはしたくないのです。

もう少しがんばってます。

またよろしくお願いします。

2013/08/02 12:45 へなちょこ への返信

度々、失礼致します。 『できれば、決められた文字列にはしたくない』という事であれば、uni-factoryさんのAppleScriptで殆ど実現可能だと思います。 重要なヒントを提示して下さっていますので、AppleScriptエディタで一行ずつ実行してみて、『イベント』や『返された値』、『結果』の欄を調べていけば、処理の仕組みが解ると思います。

2013/08/03 14:30 へなちょこ への返信

へなちょこさん、


昔、bashで似た様な事がしたいと思った事があります。また最近、AppleScriptに手を出し始めているのですが、意外とファイル操作が難しいのに驚いています。


そこで、少し条件を簡単にしたbashスクリプトを書いてみました。「~/exp」というファルダにデータが有ったとします;

ユーザがアップロードしたファイル


以下に示すbashスクリプトによって、次のようにフォルダ名と同じ文字列から始まるファイルを、そのフォルダ名の下に移動します;

ユーザがアップロードしたファイル


そのスクリプトは;



#!/bin/bash


cd $HOME/exp

ls

mylist=$(echo *)


for fd in $mylist

do

if test -d $fd

then

echo "$fd"is dir

myFiles=$(echo "${fd}?*")

for file in $myFiles

do

simple_name=$(echo "$file" | sed -e "s%^$fd%%")

mv "$file" "./$fd/$simple_name"

done

fi

done


細かくフォルダを定めたければ、フォルダ名の条件を詳しく設定する必要がありますね。


以上、ご参考まで。

2013/08/06 19:09 へなちょこ への返信

--フォルダを選択して実行

tellapplication"Finder"torepeatwitha4in (filesof (selectionasalias list)'s item 1 whose""isinnameand""isinname) asalias list


seta5tonameofa4


tellcurrent applicationtoseta5toa5's characters (offsetof""ina5) thru (offsetof""ina5) asUnicode text


try


seta6to (foldersof (selectionasalias list)'s item 1 whosea5isinname) asalias


movea4toa6


endtry

endrepeat


動きがなさそうなので、これで動くだろうと思うものをのせときます。


英語のマニュアルはちょっと・・・。

AppleScriptのマニュアルは中1レベルの英語でOKです。

英語がほぼ赤点ばかりだった私でもいけます。

頑張って読んでみましょう。

2013/08/06 20:45 へなちょこ への返信

do shell script 版です。Ruby 1.9 以降を導入してる場合は若干書き換える必要があると思います。また、正規表現はかなり手抜きで、とりあえず動く程度です。choose folder は適宜書き換えてください。


挙動はこんな感じ

【請求書】#123456.pdf → 請求書/【請求書】#123456.pdf


AppleScript

on run     try         tell application "Finder"             set dir to choose folder             my mv("*.pdf", dir)         end tell     on error err_msg         return err_msg     end try end run on mv(arg, dir)     do shell script ("         cd " & quoted form of POSIX path of dir & " &&         ruby -e 'require %[fileutils]             ARGV.each do |f|                 if /【([^\\.].*?)】/ =~ f                     dir = $1                     next if File.file?(%[#{dir}/#{f}])                     FileUtils.mkdir_p(dir)                     FileUtils.mv(f, dir)                     puts %[#{f} -> #{dir}]                 end             end         ' -- " & arg & "     ") end mv


ーーーーー


フォルダがない場合は作成するようにしてありますが、次のようにするとそのまま何もしないようになります。

[変更前] FileUtils.mkdir_p(dir) [変更後] next if ! File.directory?(dir)


また、次のようにすると、拡張子 .pdf と .txt の両方が処理対象となります。

[変更前] my mv("*.pdf", dir) [変更後] my mv("{*.pdf,*.txt}", dir)

2013/08/08 17:13 へなちょこ への返信

皆さんのご教授のもと、何とか自作で出来上がりました。

ただ一つ問題があります。

移動先に同名のファイルがあった場合に入替しません。


on FolderExistenceCheck(PText, ParentPath)

tell application "Finder"

if "【" is in PText then

if "】" is in PText then

set cn1 to the offset of "【" in PText

set cn2 to the offset of "】" in PText

if cn1 < cn2 then

set cn1 to cn1 + 1

set cn2 to cn2 - 1

set thePath to characters cn1 thru cn2 of PText as text

set CheckPath to ParentPath & thePath & ":"

if exists alias CheckPath then

set oldPath to ParentPath & PText

if exists alias oldPath then

move alias (oldPath) to alias (CheckPath) without replacing

end if

end if

end if

end if

end if

end tell

end FolderExistenceCheck



ちゃんとmove のところでwithout replacingを付けているのですが、

エラーでとまってしまいます。

ネストが深くなってかっこ悪いスクリプトである事も不満です。

入替がうまくいかない事、スマートなコードにする方法、

その辺、またアドバイス頂けたらと思います。

2013/08/08 17:59 へなちょこ への返信

入れ替えていいのならwithout ではなくwithですね。

前段階のスクリプトがないので動作確認していませんが、とりあえず。


onFolderExistenceCheck(PText, ParentPath)


tellapplication"Finder"


if""isinPTextand""isinPTextthen

set {cn1, cn2} to {offset of "" in PText, offset of "" in PText}

set thePath to characters (cn1 + 1) thru (cn2 - 1) of PText as text


set {CheckPath, oldPath} to {ParentPath & thePath & ":", ParentPath & PText}

try


movealiasoldPathtoaliasCheckPathwithoutreplacing


endtry


endif


endtell

endFolderExistenceCheck


・最初の【】判定をまとめる

・cn1、cn2など、まとめられるところはまとめる

・置き換えるだけでいいのなら、ファイル・フォルダがあるかどうかは判断させないでtry〜end tryで済ませる。

2015/08/26 12:59 Hiro__S への返信

2年前のポストに自己レス。ファイル数が多いと動かないというのを他所で見かけたので、ちょっとだけ変更してみました。


30,000ファイル → 1,000ファイルx30フォルダの振り分けで数回テストした限りでは大丈夫のようです。ただし、ファイル数があまり多いと Finder がフラフラになるので、適当なところでやめといた方が良いかと。


また、ファイル数が多い場合、結果を表示 (puts %[#{f} -> #{dir}]) すると AppleScirpt Editor がハングするので、何も表示しないようにしてあります。ログの書き出し機能は面倒なのでパス。


なお、Automator の「AppleScript を実行」は考慮してません。(Lion 以降のことは知りませんが、Snow Leopard の Automator AppleScript ではそれなりに書き換える必要があります)


変更版

on run try my mv("pdf", choose folder) on error err_msg return err_msg end try end run on mv(ext, dir) do shell script " cd " & quoted form of POSIX path of dir & " || exit 1 LANG=ja_JP.UTF-8 ruby -e ' require %[fileutils] Dir.glob(ARGV.map{|ext|%[*.#{ext}]}).each do |f| if /【([^\\.].*?)】/ =~ f dir = $1 next if File.file?(%[#{dir}/#{f}]) FileUtils.mkdir_p(dir) FileUtils.mv(f, dir) # puts %[#{f} -> #{dir}] end end ' -- " & ext & " " end mv


ーーーーー


前版とは異なり、拡張子名のみを指定するようにしてあります。

my mv("pdf", dir)


ーーーーー


動作確認


Mac OS X 10.5.8 - 少ないファイル数でテスト

・ruby 1.8.6

・ruby 2.0.0p643

・ruby 2.1.6p336

・Script Editor 2.2.1 / AppleScript 2.0.1


Mac OS X 10.6.8 - 30,000ファイルでテスト

・ruby 1.8.7

・AppleScript Editor 2.3 / AppleScript 2.1.2


# ruby 1.8.6 と 1.8.7 は OS に最初から入ってるもので、それ以外のバージョンは自分で入れたもの

AppleScript 条件によりファイルの移動

Apple サポートコミュニティへようこそ
Apple ユーザ同士でお使いの製品について助け合うフォーラムです。Apple ID を使ってご参加ください。