将从 bash 个命令返回的路径名分配给 AppleScript 列表
Assign pathnames returned from bash command(s) to an AppleScript list
我想在 Applescript 中以列表的形式提示一个目录(递归)最近添加的 10 个文件的路径。这在 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-liner 中?也许还有一个仅适用于 Applescript 的解决方案?
当您从 AppleScript "shell out" 中分配给变量的值 class
时,(即名为 l
的变量在你的例子中)总是 text and not a list.
在您的场景中,您实际上是在捕获 find 实用程序等发送到 stdout
(fd 1) 的路径名,Applescript 将其识别为 text
。
要转换每一行(即通过 bash 命令打印到 stdout
的 路径名 ),您需要使用助手 subroutine/function 如以下要点所示。
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
解释:
第一行阅读:
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 命令的结果(通常是 路径名 的 multi-line 字符串)分配给名为 AppleScript 的变量stdout
。分配给 stdout
的值的 class 将是 text
- 您可以通过在脚本中临时添加以下行来验证这一点:
log class of stdout
注意:您需要重新定义当前读取的部分; /absolute/path/to/target/directory
,带有您要搜索的 directory/folder 的真实绝对路径。您还会注意到此目标 pathname 前面有 & quoted form of
- 这只是确保给定 pathname 中的任何 space 个字符 被正确解释。
第二行读:
set latestList to transformStdoutToList(stdout)
调用 transformStdoutToList
子例程,传入 stdout
的值,并将返回的结果分配给名为 latestList
的变量。分配给 latestList
的值的 class 将是 list
。同样,您可以通过在脚本中临时添加以下行来验证这一点:
log class of latestList
transformStdoutToList
子例程转换传递给它的每一行(即路径名)并形成一个新的list
路径名。请阅读上面代码中的注释以获得进一步的解释——您会注意到它成功地处理了任何可能包含换行符的 pathname(s)。
补充说明:
前面提到的 transformStdoutToList
子例程包括一行:
set last item of pathList to last item of pathList & "\n" & aLine
"\n"
部分的存在是为了恢复 路径名 中可能存在的任何换行符。但是,当您在 AppleScript 编辑器 中编译脚本时,将显示如下:
set last item of pathList to last item of pathList & "
" & aLine
注意: 换行符,即 \n
部分已经消失,并创建了一个实际的 line-break.
这是正常的,脚本会产生预期的结果。但是,如果您想在 AppleScript 编辑器 中保留 "\n"
部分,请按如下所述更改您的首选项:
- Select
AppleScript Editor
> Preferences...
从菜单栏。
- Select
Editing
选项卡。
- 单击
Formatting: Escape tabs and line breaks in strings
的复选框(即打开此选项)。
编辑:
How can I put the bash part into a working 1-liner
如果你必须有一个"1-liner"并且愿意牺牲可读性,那么你可以这样做:
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
子例程,因此它也需要出现在您的脚本中。
我想在 Applescript 中以列表的形式提示一个目录(递归)最近添加的 10 个文件的路径。这在 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-liner 中?也许还有一个仅适用于 Applescript 的解决方案?
当您从 AppleScript "shell out" 中分配给变量的值 class
时,(即名为 l
的变量在你的例子中)总是 text and not a list.
在您的场景中,您实际上是在捕获 find 实用程序等发送到 stdout
(fd 1) 的路径名,Applescript 将其识别为 text
。
要转换每一行(即通过 bash 命令打印到 stdout
的 路径名 ),您需要使用助手 subroutine/function 如以下要点所示。
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
解释:
第一行阅读:
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 命令的结果(通常是 路径名 的 multi-line 字符串)分配给名为 AppleScript 的变量
stdout
。分配给stdout
的值的 class 将是text
- 您可以通过在脚本中临时添加以下行来验证这一点:log class of stdout
注意:您需要重新定义当前读取的部分;
/absolute/path/to/target/directory
,带有您要搜索的 directory/folder 的真实绝对路径。您还会注意到此目标 pathname 前面有& quoted form of
- 这只是确保给定 pathname 中的任何 space 个字符 被正确解释。
- 我们利用 AppleScript 的
第二行读:
set latestList to transformStdoutToList(stdout)
调用
transformStdoutToList
子例程,传入stdout
的值,并将返回的结果分配给名为latestList
的变量。分配给latestList
的值的 class 将是list
。同样,您可以通过在脚本中临时添加以下行来验证这一点:log class of latestList
transformStdoutToList
子例程转换传递给它的每一行(即路径名)并形成一个新的list
路径名。请阅读上面代码中的注释以获得进一步的解释——您会注意到它成功地处理了任何可能包含换行符的 pathname(s)。
补充说明:
前面提到的 transformStdoutToList
子例程包括一行:
set last item of pathList to last item of pathList & "\n" & aLine
"\n"
部分的存在是为了恢复 路径名 中可能存在的任何换行符。但是,当您在 AppleScript 编辑器 中编译脚本时,将显示如下:
set last item of pathList to last item of pathList & "
" & aLine
注意: 换行符,即 \n
部分已经消失,并创建了一个实际的 line-break.
这是正常的,脚本会产生预期的结果。但是,如果您想在 AppleScript 编辑器 中保留 "\n"
部分,请按如下所述更改您的首选项:
- Select
AppleScript Editor
>Preferences...
从菜单栏。 - Select
Editing
选项卡。 - 单击
Formatting: Escape tabs and line breaks in strings
的复选框(即打开此选项)。
编辑:
How can I put the bash part into a working 1-liner
如果你必须有一个"1-liner"并且愿意牺牲可读性,那么你可以这样做:
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
子例程,因此它也需要出现在您的脚本中。