将从 bash 命令返回的路径名分配给 AppleScript 列表 [英] Assign pathnames returned from bash command(s) to an AppleScript list
问题描述
我想将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
<小时>
说明:
在第一行阅读:
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 tostdout
will betext
- 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 ofstdout
and assigns the result returned to the variable namedlatestList
. The class of the value assigned tolatestList
will belist
. Again, you can verify this by temporarily adding the following line to the script:log class of latestList
transformStdoutToList
子例程转换传递给它的每一行(即路径名),并形成一个新的list
list
em>路径名.请阅读上面代码中的注释以获得进一步的解释 - 您会注意到它成功地处理了任何可能包含换行符的路径名.The
transformStdoutToList
subroutine transforms each line (i.e. a pathname) that is passed to it and forms a newlist
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:- 从菜单栏中选择
AppleScript Editor
>Preferences...
. - 选择
编辑
标签. - 单击
格式:字符串中的转义标签和换行符
的复选框(即打开此选项).
- Select
AppleScript Editor
>Preferences...
from the menu bar. - Select the
Editing
tab. - 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屋!
- 从菜单栏中选择
- we utilize AppleScript's