sed字符串中的AppleScript变量

时间:2015-04-21 20:45:29

标签: bash sed applescript

我绝不是AppleScript专家,而是过得去。我正试图将一些AppleScript变量传递给sed命令,以便根据变量替换文件中的某些文本。

我在AppleScript中有两个抓取用户数据的对话框,我存储这些变量。 myData - 这很好用。

set myData to text returned of ¬
    (display dialog "Enter Your Data" with title ¬
        "Data Entry" default answer ¬
        "" buttons {"Continue…"} ¬
        default button 1 ¬
        ) 

set searchFor to quoted form of "data1"
set searchFor2 to quoted form of "data2"
set inputFile to "/Users/User1/Desktop/file.txt"
set outputFile to "/Users/User1/Desktop/file1.txt"

do shell script quoted form of ("sed -i.bak s/" & searchFor & "/" & myData & "/g") & " " & inputFile & " > " & outputFile

我实际收到此错误:No such file or directory,退出代码127。但奇怪的是,它确实写出了包含零数据的文件。我不一定像脚本建议写出一个diff文件,只是编辑数据。但是,我没有那样成功,这就是我这样做的原因。

对我的问题的任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:4)

您的即时问题您错误地应用了quoted form of 多次,而且更重要的是quoted form of应用于sed可执行文件名称及其选项以及sed脚本一起,这些文件总是会中断(有关详细说明,请参见下文) );尝试以下操作 - 事先将quoted form of应用于任何变量 - 请注意选择性如何应用quoted form of sed 脚本以及输入和输出文件:

do shell script "sed " & quoted form of ¬
  ("s/" & searchFor & "/" & myData & "/g") ¬
  & " " & quoted form of inputFile & " > " & quoted form of outputFile

请注意,我已从命令中删除-i.bak,因为它总是会导致输出文件:-i更新输入文件到位,生成 no stdout output 。因此, nothing 将通过outputFile发送给> outputFile

但是,如果searchFormyData包含/sed正则表达式中具有特殊含义的字符,则此仍然可能会中断或行为异常< / strong>(例如,\*[,...)或替换字符串(例如&,{{1 }})。

为了避免这种情况,你必须首先转义输入字符串,不幸的是,这非常重要。

以下处理程序 提供强大的通用转义 - 它们基于this answer,其中解释了基础命令 [1] ):

\

[1]需要进行一些调整才能使它们与# Quotes (escapes) a string for safe use in a `sed` regex. on quoteRegex(txt) do shell script "sed -e 's/[^^]/[&]/g; s/\\^/\\\\^/g; $!a\\'$'\\n''\\\\n' <<<" & quoted form of txt & " | tr -d '\\n'" end quoteRegex # Quotes (escapes) a string for safe use in a `sed` substitution string (`s///` function). on quoteSubst(txt) do shell script "IFS= read -d '' -r <<<\"$(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\\]/\\\\&/g; s/\\n/\\\\&/g' <<<" & quoted form of txt & "; printf X)\"; printf %s \"${REPLY%$'\\n'X$'\\n'}\"" without altering line endings end quoteSubst 一起使用;值得注意的是,不支持流程替换(do shell script);通过<(...)的变通方法需要额外的步骤来准确地保留输入中的尾随换行符。

将上面的处理程序粘贴到您的脚本后,以下是如何将它们应用于您的命令:

<<<"$(...)"

至于你原始症状

  

但奇怪的是,它确实写出了包含零数据的文件。

这表明do shell script "sed " & quoted form of ¬ ("s/" & my quoteRegex(searchFor) & "/" & my quoteSubst(myData) & "/g") ¬ & " " & quoted form of inputFile & " > " & quoted form of outputFile (a)能够调用shell,(b)shell解析命令行而不会遇到语法错误;如果满足这些条件,则输出重定向(例如do shell script)会将目标文件创建作为零字节文件,或者,如果存在,则将其截断为零字节文件,BEFORE命令执行开始。

如果命令执行失败,则会遗留零字节文件。

  

我实际上得到了这个错误:没有这样的文件或目录,退出代码127

退出代码> outFile表示无法调用作为命令字符串第一个标记的可执行文件,因为无法找到它。

确实发生了这种情况,因为您错误地将127应用于quoted form of可执行文件名称,其选项以及sed脚本一起,这会导致将整个结果字符串解释为可执行文件名,这显然会失败。

我们举一个简化的例子:

sed

产生quoted form of "sed s/foo/bar/g file" 包括封闭的单引号。 将此字符串传递给shell会导致shell将此字符串视为构成可执行文件路径或文件名单个标记。显然,没有名为'sed s/foo/bar/g file'的文件,因此命令失败。

如上所示,解决方案是将sed s/foo/bar/g file,其选项,脚本以及输入文件名和输出文件名作为单独的标记传递。