AppleScriptは、フォルダの下に含まれる最大のファイルを深く検索できますか?


1

選択したディレクトリ内で最大のファイルを見つけ(別のフォルダ内にある場合でも)、画面にフルパスを表示するAppleScriptを作成する必要があります。

これは私がこれまで持っているものですが、動作しません:

set theItem to quoted form of POSIX path of (choose folder)

set theSize to (do shell script "/usr/bin/mdls -name kMDItemFSSize -raw " & theItem)

on open f

set filePath to do shell script "dirname " & POSIX path of f as string

display dialog theFilePath

上記のスクリプトから何が機能していないかをどのように判断したらよいかわかりません。この作品を作る次のステップを手伝ってもらえますか?

回答:


2

このタスクを実行するにはさまざまな方法があり、それぞれ長所と短所があります。シェル方法が急速あるっぽい常に最新の情報を返しません。AppleScriptのFinderインターフェイスは思ったほど遅くはありませんが、キャッシュされているファイルサイズに対して実行可能な値のみを返します。 システムイベントは、取得時に高速ですが、ファイル属性にアクセスすると速度が低下するため、通常、選択したAppleScriptファイル管理アプリケーションです。また、Finderのように深いディレクトリ列挙を行うこともできません(ただし、手動で実装することはできます)。

Objective-Cスクリプトブリッジを使用して、超高速で、ディレクトリのサブフォルダーに完全に下降できるAppleScriptを作成することにしました。全体として、これは最善の方法ですが、教師が少し疑わしいという欠点があります。

# Loads the Foundation framework into the script so that we can access its
# methods and constants
use framework "Foundation"

# Declare properties that belong to the Foundation framework for easier
# referencing within the script
property this : a reference to current application
property NSArray : a reference to NSArray of this
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to 4
property NSDirectoryEnumerationSkipsPackageDescendants : a reference to 2
property NSFileManager : a reference to NSFileManager of this
property NSSortDescriptor : a reference to NSSortDescriptor of this
property NSString : a reference to NSString of this
property NSURL : a reference to NSURL of this
property NSURLFileSizeKey : a reference to NSURLFileSizeKey of this
property NSURLNameKey : a reference to NSURLNameKey of this
property NSURLPathKey : a reference to NSURLPathKey of this

# Call the handler defined below.  This is where the script does the actual
# retrieving of the files and filesizes
get my contentsOfDirectory:"~/Downloads"

# If we stopped the script at the line above, you'd see the entire contents of 
# the directory subtree listed with file paths and filesizes, ordered in 
# descending order by filesize.  However, you only want the largest file, so
# we pick out the first item in the list.
return item 1 of the result

--------------------------------------------------------------------------------
# This is an AppleScript handler declaration
on contentsOfDirectory:dir
    local dir # This tells the handler that the variable passed as the
    # parameter is limited in scope to this handler

    # Obtain a reference to the default file manager of the filesystem
    set FileManager to NSFileManager's defaultManager()

    # This is where retrieve the contents of the directory, recursing
    # into any subfolders.  The options declared tell the method to skip
    # hidden files and not to look inside file packages, such as 
    # applications or library files.  I've declared a list of keys that
    # pre-fetch file attributes during this retrieval, making it faster
    # to access their data later: filename, full path, and file size.
    set fs to FileManager's enumeratorAtURL:(NSURL's ¬
        fileURLWithPath:((NSString's stringWithString:dir)'s ¬
            stringByStandardizingPath())) ¬
        includingPropertiesForKeys:[¬
        NSURLPathKey, ¬
        NSURLNameKey, ¬
        NSURLFileSizeKey] ¬
        options:(NSDirectoryEnumerationSkipsHiddenFiles + ¬
        NSDirectoryEnumerationSkipsPackageDescendants) ¬
        errorHandler:(missing value)

    # I created the script object just to speed up the process of
    # appending new items to the empty list it contains.
    script |files|
        property list : {}
    end script

    # This is the repeat loop that we use to enumerate the contents
    # of the directory tree that we retrieved above
    repeat
        # This allows us to access each item in the enumerator one
        # by one.
        set f to fs's nextObject()

        # Once the list has been exhausted, the value returned above
        # will be a "missing value", signifying that there are no more
        # files to enumerate.  Therefore, we can exit the loop.
        if f = missing value then exit repeat

        # Here, we retrieve the values of file attributes denoted
        # by the keys I declared earlier.  I'm picking out the path
        # and the filesize as per your needs.
        f's resourceValuesForKeys:[NSURLPathKey, NSURLFileSizeKey] ¬
            |error|:(missing value)

        # The above command returns a record containing the two
        # file attributes.  This record gets appended to the list
        # stored in the script object above.
        set end of list of |files| to the result as record
    end repeat

    # The list in the script object is an AppleScript list object.  For
    # the next part, I need a cocoa list object (NSArray).
    set L to item 1 of (NSArray's arrayWithObject:(list of |files|))

    # This defines a sort descriptor which is used to sort the array.
    # I'm telling it to use the filesize key to sort the array by 
    # filesize, which will let us grab the largest file easily.
    set descriptor to NSSortDescriptor's alloc()'s ¬
        initWithKey:"NSURLFileSizeKey" ascending:no

    # Sort the list.
    L's sortedArrayUsingDescriptors:[descriptor]

    # Return the result.
    result as list
end contentsOfDirectory:

1

これは、他の回答で使用されているAppleScript Objective-C コードの代替として提供されており、OPに示されている標準の AppleScript コードに沿ったものです。この回答は、他の回答の作成者であるCJKに帰属することに注意してください。CJKは、元の回答の下で互いに削除したコメントから派生しているためです。また、複雑さにもかかわらず、彼の答えは、ここで提供されているものよりもパフォーマンスが優れていると考えています。

このスクリプトを実行すると、ユーザーはフォルダーを選択し、その結果、サブフォルダーを含む選択したフォルダー内の最大ファイルパス名がダイアログボックスに表示されます。

AppleScript コードの例:

set chosenFolder to quoted form of POSIX path of ¬
    (text items 1 thru -2 of ((choose folder) as text) as text)

set theLargestFilePathname to ¬
    (do shell script "find " & chosenFolder & ¬
        " -type f -ls | sort -nrk7 | awk '{for(i=11; i<=NF; ++i) printf $i\"\"FS; exit}'")

display dialog "The largest file within the chosen folder, and its subfolders, is:" & ¬
    linefeed & linefeed & theLargestFilePathname buttons {"OK"} default button 1 ¬
    -- giving up after 3        # Remove the '--' at the front of this line to enable this.

ダウンロードフォルダの最終結果は、次のダイアログボックスです。

表示ダイアログボックス

表示されているパスファイル名は、現時点では、ディスク上の5.27 GBにあるダウンロードフォルダー内の最大ファイルです。


注:AppleScript コード はそれだけであり、適切なエラー処理は含まれていません。ユーザーは、適切、必要、または必要に応じてエラー処理を追加する責任があります。


@CJK、回答から削除されたコメントに一部基づいてこの回答を追加しました。
user3439894

1
そして、私はそれが+1に値すると思います。
CJK
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.