CSVで列指定ソート

NSComparatorを使えないので苦肉の策
ソートの優先順位を自由に変更できるので
今後使っていこうかな
001 | #!/usr/bin/env osascript |
002 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
003 | (* |
004 | 【前提条件】 |
005 | CSVファイルはダブルクオテーション無し |
006 | UTF8で作成されていること |
007 | 項目の値にカンマが含まれていないこと |
008 | |
009 | com.cocolog-nifty.quicktimer.icefloe *) |
010 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
011 | use AppleScript version "2.8" |
012 | use framework "Foundation" |
013 | use framework "AppKit" |
014 | use scripting additions |
015 | property refMe : a reference to current application |
016 | |
017 | ########################## |
018 | #何列目の値でソートする? |
019 | set numSortRowNo to 6 as integer |
020 | #1行目は表題? |
021 | set boolFirstLine to true as boolean |
022 | |
023 | ########################## |
024 | # |
025 | set aliasPathToMe to (path to me) as alias |
026 | tell application "Finder" |
027 | set aliasContainerDirPath to (container of aliasPathToMe) as alias |
028 | set aliasFilePath to (file "擬似住所録.csv" of folder aliasContainerDirPath) as alias |
029 | end tell |
030 | set strFilePath to (POSIX path of aliasFilePath) as text |
031 | set ocidFilePathStr to refMe's NSString's stringWithString:(strFilePath) |
032 | set ocidFilePath to ocidFilePathStr's stringByStandardizingPath() |
033 | set ocidFilePathURL to refMe's NSURL's alloc()'s initFileURLWithPath:(ocidFilePath) isDirectory:(false) |
034 | set strExtensionName to ocidFilePathURL's pathExtension() as text |
035 | #拡張子を取って |
036 | set ocidBaseFilePathURL to ocidFilePathURL's URLByDeletingPathExtension() |
037 | set strSaveExtension to ("ソート済." & strExtensionName & "") as text |
038 | set ocidSaveFilePathURL to ocidBaseFilePathURL's URLByAppendingPathExtension:(strSaveExtension) |
039 | ########################## |
040 | #テキスト読み込み |
041 | set listReadStrings to refMe's NSString's alloc()'s initWithContentsOfURL:(ocidFilePathURL) encoding:(refMe's NSUTF8StringEncoding) |error|:(reference) |
042 | set ocidReadStrings to (item 1 of listReadStrings) |
043 | #改行をUNIXに強制 |
044 | set ocidReadStrings to (ocidReadStrings's stringByReplacingOccurrencesOfString:("\r\n") withString:("\n")) |
045 | set ocidReadStrings to (ocidReadStrings's stringByReplacingOccurrencesOfString:("\r") withString:("\n")) |
046 | set ocidReadStrings to (ocidReadStrings's stringByReplacingOccurrencesOfString:("\n\n") withString:("\n")) |
047 | #タブは除去しておく |
048 | set ocidReadStrings to (ocidReadStrings's stringByReplacingOccurrencesOfString:("\t") withString:("")) |
049 | #改行終わりをチェック |
050 | #改行終わりのテキストをArrayにすると最後の項目が空になるので |
051 | #エラー対応 |
052 | set boolLastChar to ocidReadStrings's hasSuffix:("\n") |
053 | if boolLastChar is true then |
054 | set numLastChar to 2 |
055 | else if boolLastChar is false then |
056 | set numLastChar to 1 |
057 | end if |
058 | ########################## |
059 | #ソートに使うDICTの初期化 |
060 | set ocidLineDict to refMe's NSMutableDictionary's alloc()'s init() |
061 | #改行でARRAYに |
062 | set ocidLineArray to ocidReadStrings's componentsSeparatedByString:("\n") |
063 | set numCntArray to ocidLineArray's |count|() |
064 | #1行目を飛ばすか? |
065 | if boolFirstLine is true then |
066 | #1行目を確保しておく |
067 | set ocidFirstLine to ocidLineArray's firstObject() |
068 | set numStartNo to 1 as integer |
069 | else if boolFirstLine is false then |
070 | set numStartNo to 0 as integer |
071 | end if |
072 | #全行巡回 |
073 | repeat with itemLineNo from numStartNo to (numCntArray - numLastChar) by 1 |
074 | set ocidLineString to (ocidLineArray's objectAtIndex:(itemLineNo)) |
075 | #行を区切り文字でArrayにして |
076 | set ocidItemsArray to (ocidLineString's componentsSeparatedByString:(",")) |
077 | #検索対象を取り出して |
078 | set ocidSortKey to (ocidItemsArray's objectAtIndex:(numSortRowNo - 1)) |
079 | #行Arrayの最初の項目に入れます |
080 | (ocidItemsArray's insertObject:(ocidSortKey) atIndex:(0)) |
081 | #テキストにしてこれをキーにします |
082 | set ocidKeyText to (ocidItemsArray's componentsJoinedByString:("")) |
083 | #↑をキーに Valueは行テキストのDICTにします |
084 | set ocidKeyDict to refMe's NSMutableDictionary's alloc()'s init() |
085 | (ocidLineDict's setValue:(ocidLineString) forKey:(ocidKeyText)) |
086 | end repeat |
087 | |
088 | ########################## |
089 | #キーのソート(方法は要カスタマイズ) |
090 | set ocidAllKeys to ocidLineDict's allKeys() |
091 | |
092 | #ソート |
093 | set ocidDescriptor to refMe's NSSortDescriptor's sortDescriptorWithKey:("self") ascending:(yes) selector:("localizedStandardCompare:") |
094 | set ocidDescriptorArray to refMe's NSArray's arrayWithObject:(ocidDescriptor) |
095 | set ocidSortedKeyArray to ocidAllKeys's sortedArrayUsingDescriptors:(ocidDescriptorArray) |
096 | |
097 | ########################## |
098 | #ソート後のテキスト |
099 | set ocidOutputArray to refMe's NSMutableArray's alloc()'s init() |
100 | if boolFirstLine is true then |
101 | #1行目を戻す |
102 | ocidOutputArray's addObject:(ocidFirstLine) |
103 | end if |
104 | #ソート済みのキーを順に処理 |
105 | repeat with itemSortedKey in ocidSortedKeyArray |
106 | #値=行テキストを取り出します |
107 | set ocidListStringValue to (ocidLineDict's objectForKey:(itemSortedKey)) |
108 | #値を出力用のArrayに入れて |
109 | (ocidOutputArray's addObject:(ocidListStringValue)) |
110 | end repeat |
111 | |
112 | ########################## |
113 | #UNIX改行でテキストに戻す |
114 | set ocidJoinText to ocidOutputArray's componentsJoinedByString:("\n") |
115 | |
116 | ########################## |
117 | #保存 |
118 | set listDone to ocidJoinText's writeToURL:(ocidSaveFilePathURL) atomically:(true) encoding:(refMe's NSUTF8StringEncoding) |error|:(reference) |
119 | if (item 1 of listDone) is true then |
120 | return "正常終了" |
121 | else if (item 1 of listDone) is false then |
122 | log (item 2 of listDone)'s localizedDescription() as text |
123 | return "保存に失敗しました" |
124 | end if |
125 |