将从 bash 命令返回的路径名分配给 AppleScript 列表 [英] Assign pathnames returned from bash command(s) to an AppleScript list

查看:28
本文介绍了将从 bash 命令返回的路径名分配给 AppleScript 列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将Applescript中最近添加的目录的10个文件的路径(递归)作为列表提示.这在 bash 中工作正常:

I want to prompt the paths of the 10 recently added files of a directory (recursively) in Applescript as a list. This works fine in 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 变量中:

I’d like to store the resulting array in an Applescript Variable:

set l to (do shell script "______________")

如何将 bash 部分放入工作的 1-liner 中?也许还有一个仅限 Applescript 的解决方案?

How can I put the bash part into a working 1-liner? Maybe there is also an Applescript-only solution?

推荐答案

当您从 AppleScript shell out" 时,您分配给变量的值的 class,(即在您的示例中名为 l 的变量)将始终为 text 并且不是list.

When you "shell out" from AppleScript the class of the value that you assign to a variable, (i.e. the variable named l in your example), will always be text and not a list.

在您的场景中,您实际上是在捕获 find 实用程序的路径名等发送到 stdout (fd 1),Applescript 将其识别为 text.

In your scenario you're essentially capturing the pathname(s) that the find utility etc send to stdout (fd 1) which Applescript just recognizes as text.

要转换每一行(即通过 bash 命令打印到 stdout路径名),您需要使用帮助器 子程序/函数 如以下要点所示.

To convert each line (i.e. a pathname that is printed to stdout via your bash commands) you'll need to utilize a helper subroutine/function as shown in the following gist.

  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. 在第一行阅读:

  1. In the first line reading:

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 的多行字符串)分配给名为 stdout 的 AppleScript 变量.分配给 stdout 的值的类将是 text - 您可以通过将以下行临时添加到脚本中来验证这一点:

    • we utilize AppleScript's do shell script command to execute your bash commands.
    • Assign the result of the bash commands (which is typically a multi-line string of pathnames) to the AppleScript variable named stdout. The class of the value assigned to stdout will be text - you can verify this by temporarily adding the following line to the script:

      log class of stdout
      

    • 注意:您需要重新定义当前读取的部分;/absolute/path/to/target/directory,带有您要搜索的目录/文件夹的真实绝对路径.您还会注意到此目标 pathname 前面带有 & 的引用形式 - 这只是确保给定 pathname 中的任何空格字符都被正确解释.

    • Note: You'll need to redefine the part that currently reads; /absolute/path/to/target/directory, with a real absolute path to the directory/folder that you want to search. You'll also notice that this target pathname is preceded with & quoted form of - this just ensures any space character(s) in the given pathname are interpreted correctly.

      第二行:

      set latestList to transformStdoutToList(stdout)
      

      调用transformStdoutToList 子程序,传入stdout 的值,并将返回的结果赋给名为latestList 的变量.分配给 latestList 的值的类将是 list.同样,您可以通过在脚本中临时添加以下行来验证这一点:

      invokes the transformStdoutToList subroutine passing in the value of stdout and assigns the result returned to the variable named latestList. The class of the value assigned to latestList will be list. Again, you can verify this by temporarily adding the following line to the script:

      log class of latestList
      

    • transformStdoutToList 子例程转换传递给它的每一行(即路径名),并形成一个新的 list listem>路径名.请阅读上面代码中的注释以获得进一步的解释 - 您会注意到它成功地处理了任何可能包含换行符的路径名.

    • The transformStdoutToList subroutine transforms each line (i.e. a pathname) that is passed to it and forms a new list of pathname(s). Please read the comments in the code above for further explanation - you'll notice that is successfully handles any pathname(s) that may include newline character(s).

      <小时>

      附加说明:

      前面提到的 transformStdoutToList 子程序包括一行内容:

      The aforementioned transformStdoutToList subroutine includes a line that reads:

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

      "\n" 部分的存在是为了恢复路径名中可能存在的任何换行符.但是,当您在 AppleScript 编辑器 中编译脚本时,它会显示如下:

      The "\n" part exists to reinstate any newline characters that may exist in a pathname. However when you compile the script in the AppleScript Editor this will appear as follows:

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

      注意:换行符,即 \n 部分已经消失并创建了一个实际的换行符.

      Note: the newline character, i.e. the \n part, has disappeared and has created an actual line-break.

      这是正常的,脚本会产生预期的结果.但是,如果您想在 AppleScript 编辑器中保留 "\n" 部分,请按如下所述更改您的首选项:

      This is normal and the script will produce the expected result. However, if you want to preserve the "\n" part in your AppleScript Editor then please change your preferences as described below:

      1. 从菜单栏中选择 AppleScript Editor > Preferences....
      2. 选择编辑标签.
      3. 单击格式:字符串中的转义标签和换行符的复选框(即打开此选项).
      1. Select AppleScript Editor > Preferences... from the menu bar.
      2. Select the Editing tab.
      3. Click the checkbox for the Formatting: Escape tabs and line breaks in strings (i.e. switch this option on).

      <小时>

      如何将 bash 部分放入一个有效的 1-liner

      How can I put the bash part into a working 1-liner

      如果你必须有一个1-liner"并且愿意牺牲可读性,那么你可以做这样的事情:

      If you must have a "1-liner" and are willing to sacrifice readability then you could do something like this instead:

      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 子例程,因此它也需要出现在您的脚本中.

      However, you'll still need to utilize the aforementioned transformStdoutToList subroutine, so that will need to be present in your script too.

      这篇关于将从 bash 命令返回的路径名分配给 AppleScript 列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆