5

在 AppleScript 中,可以使用以下行获取当前脚本所在文件夹的 POSIX 路径:

POSIX path of ((path to me as text) & "::")

示例结果:/Users/aaron/Git/test/

什么是 JavaScript 等价物?

4

7 回答 7

8

不涉及 ObjC 的纯 JXA 代码:

App = Application.currentApplication()
App.includeStandardAdditions = true
SystemEvents = Application('System Events')

var pathToMe = App.pathTo(this)
var containerPOSIXPath = SystemEvents.files[pathToMe.toString()].container().posixPath()
于 2015-07-12T14:38:17.440 回答
4

这是一种方法[注意:我不再推荐这种方法。请参阅下面的编辑]

app = Application.currentApplication();
app.includeStandardAdditions = true;
path = app.pathTo(this);
app.doShellScript('dirname \'' + path + '\'') + '/';

path请注意在 doShellScript 中使用带有空格等的路径的单引号

编辑 在被@foo拍打后使用相当不安全的路径引用方法,我想修改这个答案:

ObjC.import("Cocoa");
app = Application.currentApplication();
app.includeStandardAdditions = true;
thePath = app.pathTo(this);

thePathStr = $.NSString.alloc.init;
thePathStr = $.NSString.alloc.initWithUTF8String(thePath);
thePathStrDir = (thePathStr.stringByDeletingLastPathComponent);

thePathStrDir.js + "/";

当然,如果你要使用这个字符串,你仍然需要处理它是否包含有问题的字符。但至少在现阶段这不是问题。这也演示了一些可供 JXA 用户使用的概念,例如使用 ObjC 桥以及.js将字符串“强制”转换为 JavaScript 字符串(来自 NSString)。

于 2015-02-27T20:54:50.610 回答
3

所以总结一下我现在在做什么,我正在回答我自己的问题。使用@foo 和@CRGreen 的出色回应,我得出以下结论:

ObjC.import('Foundation');
var app, path, dir;

app = Application.currentApplication();
app.includeStandardAdditions = true;

path = app.pathTo(this);
dir = $.NSString.alloc.initWithUTF8String(path).stringByDeletingLastPathComponent.js + '/';

这与@CRGreen 的响应非常接近,但是,它更简洁一些,我正在导入Foundation而不是Cocoa. 另外,我声明了我用来避免意外全局变量的变量。

于 2015-03-01T11:22:16.477 回答
3

通过提供独立的实用功能来补充有用的现有答案:

// Return the POSIX path of the folder hosting this script / app.
// E.g., from within '/foo/bar.scpt', returns '/foo'.
function myPath() {
    var app = Application.currentApplication(); app.includeStandardAdditions = true
    return $(app.pathTo(this).toString()).stringByDeletingLastPathComponent.js
}

// Return the filename root (filename w/o extension) of this script / app.
// E.g., from within '/foo/bar.scpt', returns 'bar'.
// (Remove `.stringByDeletingPathExtension` if you want to retain the extension.)
function myName() {
    var app = Application.currentApplication(); app.includeStandardAdditions = true
    return $(app.pathTo(this).toString()).lastPathComponent.stringByDeletingPathExtension.js
}

注意:这些函数利用了 ObjC 桥的快捷语法形式$(...)forObjC.wrap().jsfor ObjC.unwrap(),并且还利用了框架的符号默认Foundation可用这一事实- 请参阅OS X 10.10 JXA 发行说明


很容易概括这些函数以提供POSIX实用程序的等价物dirnamebasename

// Returns the parent path of the specified filesystem path.
// A trailing '/' in the input path is ignored.
// Equivalent of the POSIX dirname utility.
// Examples:
//    dirname('/foo/bar') // -> '/foo'
//    dirname('/foo/bar/') // ditto
function dirname(path) {
  return $(path.toString()).stringByDeletingLastPathComponent.js
}

// Returns the filename component of the specified filesystem path.
// A trailing '/' in the input path is ignored.
// If the optional <extToStrip> is specified:
//   - If it it is a string, it is removed from the result, if it matches at
//     the end (case-sensitively) - do include the '.'
//   - Otherwise (Boolean or number), any truthy value causes any extension
//     (suffix) present to be removed.
// Equivalent of the POSIX basename utility; the truthy semantics of the
// 2nd argument are an extension.
// Examples:
//    basename('/foo/bar') // -> 'bar'
//    basename('/foo/bar/') // ditto
//    basename('/foo/bar.scpt', 1) // -> 'bar'
//    basename('/foo/bar.scpt', '.scpt') // -> 'bar'
//    basename('/foo/bar.jxa', '.scpt') // -> 'bar.jxa'
function basename(path, extToStrip) {
  path = path.toString()
  if (path[path.length-1] === '/') { path = path.slice(0, -1) }
  if (typeof extToStrip === 'string') {
    return path.slice(-extToStrip.length) === extToStrip ? $(path).lastPathComponent.js.slice(0, -extToStrip.length) : $(path).lastPathComponent.js    
  } else { // assumed to be numeric: if truthy, strip any extension
    return extToStrip ? $(path).lastPathComponent.stringByDeletingPathExtension.js : $(path).lastPathComponent.js    
  }
}
于 2015-10-13T03:30:32.933 回答
2

使用-[NSString stringByDeletingLastPathComponent],它已经知道如何安全地删除最后一个路径段:

ObjC.import('Foundation')

path = ObjC.unwrap($(path).stringByDeletingLastPathComponent)

或者,如果您喜欢更危险的生活,您可以使用正则表达式从 POSIX 路径字符串中删除最后一个路径段。在我的头顶(警告购买者等):

path = path.replace(/\/[^\/]+\/*$/,'').replace(/^$/,'/')

(请注意,第二个replace()是正确处理具有 <2 个部分的路径所必需的。)

于 2015-02-28T14:12:31.187 回答
2

我想我找到了一种更简单的方法来获取父文件夹而不调用 ObjC。

var app = Application.currentApplication();
app.includeStandardAdditions = true;
thePath = app.pathTo(this);

Path(thePath + '/../../')
于 2015-03-16T22:06:32.207 回答
-2

上面有很多有趣的解决方案。

这是我的,它不需要 ObjC,并返回一个具有可能需要的属性的对象。

'use strict';
var oScript = getScriptProp(this);

/*oScript Properties
    Path
    Name
    ParentPath
    Folder
*/

oScript.ParentPath;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function getScriptProp(pRefObject) {

  var app = Application.currentApplication()
  app.includeStandardAdditions = true

  var pathScript = app.pathTo(pRefObject).toString();
  var pathArr = pathScript.split("/")

  var oScript = {
    Path: pathScript,
    Name: pathArr[pathArr.length - 1],
    ParentPath: pathArr.slice(0, pathArr.length - 1).join("/"),
    Folder: pathArr[pathArr.length - 2]
  };

  return oScript
}
于 2017-05-01T03:06:59.617 回答