Присвойте пути, возвращенные командами bash, списку AppleScript - PullRequest
0 голосов
/ 29 мая 2019

Я хочу предложить список 10 недавно добавленных файлов каталога (рекурсивно) в Applescript в виде списка. Это прекрасно работает в Bash:

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

array=(`find . -type f -print0 | xargs -0 ls -t | head -n 10`)

echo "${array[*]}"

IFS=$SAVEIFS

Я хочу сохранить полученный массив в переменной Applescript:

set l to (do shell script "______________")

Как я могу поместить часть bash в рабочий 1-вкладыш? Может быть, есть также решение только для Applescript?

1 Ответ

0 голосов
/ 29 мая 2019

Когда вы "выкладываете" из AppleScript, class значения, которое вы назначаете переменной (т. Е. Переменной с именем l в вашем примере), всегда будет текст и не a список .

В вашем сценарии вы, по сути, захватываете пути (имена), которые утилита find и т. Д. Посылает на stdout (fd 1), который Applescript распознает как text.

Чтобы преобразовать каждую строку (т. Е. путь , который печатается в stdout с помощью команд bash), вам необходимо использовать вспомогательную подпрограмму / функцию , как показано в следующая суть.

  set stdout to do shell script "/usr/bin/find " & quoted form of "/absolute/path/to/target/directory" & " -type f -print0 | xargs -0 ls -t | head -n 10"

  set latestList to transformStdoutToList(stdout)

  -- Test it's a proper AppleScript list.
  log class of latestList
  log (item 1 of latestList)
  log (item 2 of latestList)
  -- ...

  (**
   * Transforms each line printed to stdout to form a new list of pathnames.
   *
   * Pathname(s) may contain newline `\n` characters in any part, including
   * their basenames. Below we read each line, if it begins with a forward
   * slash `/` it is considered to be the start of a pathname. If a line does
   * not begin with a forward slash `/` it is considered to be part of the
   * prevous pathname. In this scenario the line is appended to previous item
   * of the list and the newline character `\n` is reinstated.
   *
   * @param {String} pathsString - The pathname(s) printed to stdout.
   * @return {List} - A list whereby each item is a pathname.
   *)
  on transformStdoutToList(pathsString)
    set pathList to {}
    repeat with aLine in paragraphs of pathsString
        if aLine starts with "/" then
            set end of pathList to aLine
        else
            set last item of pathList to last item of pathList & "\n" & aLine
        end if
    end repeat
    return pathList
  end transformStdoutToList

Пояснение:

  1. В первой строке читается:

    set stdout to do shell script "/usr/bin/find " & quoted form of "/absolute/path/to/target/directory" & " -type f -print0 | xargs -0 ls -t | head -n 10"
    
    • мы используем команду AppleScript do shell script для выполнения команд bash.
    • Назначьте результат команд bash (обычно это многострочная строка pathnames ) переменной AppleScript с именем stdout. Класс значения, присвоенного stdout, будет text - это можно проверить, временно добавив в скрипт следующую строку:

      log class of stdout
      
    • Примечание: Вам необходимо переопределить часть, которая в данный момент читает; /absolute/path/to/target/directory, с реальным абсолютным путем к каталогу / папке, которую вы хотите найти. Вы также заметите, что этой цели pathname предшествует & quoted form of - это просто гарантирует, что любые пробельные символы в данном pathname будут правильно интерпретированы.

  2. Вторая строка:

    set latestList to transformStdoutToList(stdout)
    

    вызывает подпрограмму transformStdoutToList, передающую значение stdout, и присваивает возвращаемый результат переменной с именем latestList. Класс значения, присвоенного latestList, будет list. Опять же, вы можете убедиться в этом, временно добавив следующую строку в скрипт:

    log class of latestList
    
  3. Подпрограмма transformStdoutToList преобразует каждую строку (то есть pathname ), которая передается ей, и формирует новый list из pathname (s) . Пожалуйста, прочитайте комментарии в приведенном выше коде для дальнейшего объяснения - вы заметите, что он успешно обрабатывает любые путей (ей) , которые могут содержать символы новой строки.


Дополнительное примечание:

Вышеупомянутая подпрограмма transformStdoutToList содержит строку, которая гласит:

set last item of pathList to last item of pathList & "\n" & aLine

Часть "\n" существует для восстановления любых символов новой строки, которые могут существовать в pathname . Однако при компиляции сценария в AppleScript Editor это будет выглядеть следующим образом:

set last item of pathList to last item of pathList & "
" & aLine

Примечание: символ перевода строки, то есть часть \n, исчез и создал фактический разрыв строки.

Это нормально, и скрипт выдаст ожидаемый результат . Однако, если вы хотите сохранить часть "\n" в вашем AppleScript Editor , измените настройки, как описано ниже:

  1. Выберите AppleScript Editor> Preferences... в строке меню.
  2. Выберите вкладку Editing.
  3. Установите флажок для Formatting: Escape tabs and line breaks in strings (т.е. включите эту опцию).

Edit:

Как я могу поместить часть bash в рабочий 1-лайнер

Если вы должны иметь "1-строчный" и готовы пожертвовать удобочитаемостью, тогда вы можете сделать что-то вроде этого:

set l to transformStdoutToList(do shell script "/usr/bin/find " & quoted form of "/absolute/path/to/target/directory" & " -type f -print0 | xargs -0 ls -t | head -n 10")

Однако вам все равно придется использовать вышеупомянутую подпрограмму transformStdoutToList, так что она также должна присутствовать в вашем скрипте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...