У меня нет конкретного решения, которое определенно решит вашу проблему, но у меня есть ряд замечаний по поводу вашего сценария с рекомендациями о том, как его можно изменить для повышения его скорости, надежности и соблюдения принципов наилучшей практики. .
Избавьтесь от этого try
блока. Вы не представляете, что происходит в вашем скрипте, когда что-то идет не так, если вы маскируете ошибки с ненужным перехватом ошибок. Единственная строка, которая должна быть заключена в try...end try
, это do shell script
, но вставляйте ее только тогда, когда вы знаете, что ваш код работает. В общем, следует использовать только блоки try
:
- когда ваш сценарий может выдать ошибку, которая полностью предсказуема и объяснима , и вы понимаете причины, по которым и при каких условиях возникает ошибка, позволяющая реализовать эффективный метод обработки ошибок;
- вокруг наименьшего возможного количества строк кода, в которых возникает ошибка, оставляя все строки кода, существование которых не зависит от результата оператора, подверженного ошибкам (с); * 1 028 *
- после того, как ваш сценарий был написан, протестирован и отлажен, где размещение блока (ов)
try
больше не служит для принудительного продолжения выполнения сценария после неудобной ошибки неизвестного происхождения, но имеет явное и четко определенная функция для выполнения в гармонии с вашим кодом, а не против него.
Как общее правило в AppleScript, не используйте Finder для выполнения операций файловой системы, если вы можете избежать этого: он медленный и блокируется во время выполнения операций, то есть вы можете ' T взаимодействовать с GUI в течение этого времени. Вместо этого используйте Системные события . Это безликое приложение, которое не остановит работу других вещей при выполнении задачи; это быстро, в контексте AppleScript и, в частности, Finder , и оно не склонно к тайм-ауту настолько, как Finder ; он обрабатывает пути posix изначально (, включая расширение тильд), без какого-либо принуждения, необходимого при использовании POSIX file
; он возвращает alias
объекты, которые являются универсальным классом файловых объектов, которые понимает каждое другое приложение с поддержкой скриптов.
В нескольких случаях Finder по-прежнему необходим. Системные события не может reveal
файл; и при этом он не может получить выбранные вами файлы в Finder . Но достаточно просто Finder получить selection
как alias list
, а затем переключиться на Системные события , чтобы выполнить фактическую обработку файлов в этом списке.
Это любопытно:
set filename to name of afile
set fname to text 1 thru ((offset of "." in filename) - 1) of filename
Правильно ли я думаю, что fname
намеревается содержать только часть имени базового файла в имени файла, и эта операция предназначена для удаления расширения? Это довольно хорошая первая попытка, и она отлично подходит для использования text
здесь для упорядочивания компонентов строки, а не characters
. Но это, конечно, в конечном итоге обрезает намного больше, чем просто расширение файла, если имя файла содержит более одного "."
, что не редкость.
Одним из способов безопасной кастрации конца имени файла является использование text item delimiters
:
set filename to the name of afile
set fname to the filename
set my text item delimiters to "."
if "." is in the filename then set fname to text items 1 thru -2 of the filename as text
Затем вы должны быть внимательны или сбрасывать text item delimiters
после этого, иначе будут последствия, если вы попытаетесь объединить строки вместе.
Другим способом прерывания расширения без использования text item delimiters
является сканирование строк, когда вы перебираете символы строки, выполняя операции или тесты по ходу работы и достигая желаемого результата. Это быстрее, чем кажется, и мощный метод для очень сложного поиска строк и манипуляций:
set filename to the name of afile
set fname to the filename
repeat while the last character of fname ≠ "."
set fname to text 1 thru -2 of fname
end
set fname to text 1 thru -2 of fname
Вы также можете получить свойство name extension
файла, получить его длину и удалить (1 + that)
много символов в конце имени файла. Существует множество способов достижения того же результата.
Это неправильно в данном конкретном случае:
set myKeywords to ((characters var1 thru var2 of myvar) as string)
characters
создает list
, который затем необходимо объединить обратно в string
, и это небезопасно, если вы не уверены, на что установлен text item delimiters
. Поскольку вы не указали на это в своем скрипте, для следует установить в пустую строку, что приведет к объединению символов обратно в слова, что приведет к ожидаемому результату. Однако это не может быть так, если, скажем, вы выполнили первую технику кастрации расширений файлов и пренебрегли установкой text item limiters
назад - тогда результирующая строка будет иметь период между каждой отдельной буквой.
Как политика в AppleScript (которую вы лично можете придерживаться или игнорировать), некоторые считают ее плохой формой, если вы выполняете операции приведения списка к строке без , сначала устанавливая text item delimiters
в окончательное значение.
Но вам не нужно делать это здесь, потому что вместо characters
используйте text
:
set myKeywords to text var1 thru var2 of myvar
Вы выполняете команду оболочки, которая выглядит следующим образом: mdls -name kMDItemKeywords <file>
, а затем две строки AppleScript, которые следуют неловко, пытаются обрезать начальные и конечные скобки вокруг текстового представления массива bash. Вместо этого вы можете включить флаг -raw
для mdls
, что упрощает вывод, удаляя для вас имя ключа. Это тогда помещает круглые скобки как самые первые и самые последние символы; однако, так как в выводе также есть множество мертвых пробелов, вы можете также получить bash, чтобы выполнить всю очистку за вас:
mdls -raw -name kMDItemContentTypeTree <file> | grep -E -io '[^()",[:blank:]]+'
Это игнорирует круглые скобки, двойные кавычки, запятые и пробелы, поэтому все, что вы получите, - это список ключевых слов, по одному на строку, без лишнего багажа. Если вам нужно их разбить на части, вы можете установить переменную the paragraphs of
для вывода команды do shell script
, которая разбивает текст на строки, помещая каждое ключевое слово в список. Но здесь кажется, что вам нужен текст, и он не против того, чтобы он был мультилинейным.
Когда я начал писать этот ответ, у меня не было ни малейшего представления о том, что стало причиной конкретной проблемы, которая привела вас сюда. Изучив детали того, как mdls
форматирует вывод, я вижу, что проблема в том, что строка myKeywords
будет содержать кучу двойных кавычек, и вы окружили размещение сущности myKeywords
в вашем выражении JavaScript с двойными кавычками. Все эти кавычки экранируются одинаково и только один раз только в среде AppleScript, но не в среде JavaScript, что приводит к тому, что каждая соседняя двойная кавычка выступает в качестве пары открытия-закрытия. Я запустил аналогичную команду в bash, чтобы получить массив значений (kMDContentTreeType
), а затем обработал текст так, как это делает AppleScript, прежде чем открыть консоль JavaScript в моем браузере и вставить ее, чтобы проиллюстрировать происходящее:
Все, что в красном, содержится внутри строки; поэтому все остальное принимается в качестве идентификатора или объекта JavaScript (или это может быть, если испорченные кавычки не испортят синтаксис, а затем приведут к неопределенной строке, которая по-прежнему ожидает пару последних кавычек с *. 1141 *