cyb*_*rfr 0 bash applescript sed
我绝不是 AppleScript 专家,但也过得去。sed我在尝试将一些 AppleScript 变量传递给命令以便根据变量替换文件中的某些文本时遇到了麻烦。
我在 AppleScript 中有两个对话框可以获取用户数据,并存储这些变量。myData- 这工作正常。
set myData to text returned of \xc2\xac\n (display dialog "Enter Your Data" with title \xc2\xac\n "Data Entry" default answer \xc2\xac\n "" buttons {"Continue\xe2\x80\xa6"} \xc2\xac\n default button 1 \xc2\xac\n ) \n\nset searchFor to quoted form of "data1"\nset searchFor2 to quoted form of "data2"\nset inputFile to "/Users/User1/Desktop/file.txt"\nset outputFile to "/Users/User1/Desktop/file1.txt"\n\ndo shell script quoted form of ("sed -i.bak s/" & searchFor & "/" & myData & "/g") & " " & inputFile & " > " & outputFile\nRun Code Online (Sandbox Code Playgroud)\n\n我实际上收到此错误:No such file or directory,退出代码127。但奇怪的是,它确实写出了其中包含零数据的文件。我不一定要按照脚本的建议写出 diff 文件,只需就地编辑数据即可。然而,我以这种方式取得的成功为零,这就是我这样做的原因。
任何对我的问题的帮助将不胜感激!
\n您面临的直接问题是您错误地多次应用quoted form of ,更重要的是, 将可执行文件名称、其选项和脚本一起应用,这总是会中断(请参阅quoted form ofsedsed下面的详细说明);尝试以下操作 -不事先应用于任何quoted form of变量- 请注意如何分别有选择地应用于脚本以及输入和输出文件:quoted form ofsed
do shell script "sed " & quoted form of \xc2\xac\n ("s/" & searchFor & "/" & myData & "/g") \xc2\xac\n & " " & quoted form of inputFile & " > " & quoted form of outputFile\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,我已从您的命令中删除-i.bak,因为它总是会导致空输出文件:就地-i更新输入文件,不产生 stdout 输出。因此,没有任何内容会被发送到outputFile> outputFile任何内容。
然而,如果和包含在正则表达式(例如,, , , ...)或替换字符串(例如,, )中具有特殊含义的字符,这仍然可能会中断或行为不当searchFormyData/sed。\\*[&\\
为了避免这种情况,您必须首先转义输入字符串,不幸的是,这并不简单。
\n\n以下处理程序 提供了强大的通用转义- 它们基于此答案,其中解释了底层命令[1]):
\n\n# Quotes (escapes) a string for safe use in a `sed` regex.\non quoteRegex(txt)\n\n do shell script "sed -e \'s/[^^]/[&]/g; s/\\\\^/\\\\\\\\^/g; $!a\\\\\'$\'\\\\n\'\'\\\\\\\\n\' <<<" & quoted form of txt & " | tr -d \'\\\\n\'"\n\nend quoteRegex\n\n# Quotes (escapes) a string for safe use in a `sed` substitution string (`s///` function).\non quoteSubst(txt)\n\n 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\n\nend quoteSubst\nRun Code Online (Sandbox Code Playgroud)\n\n[1] 需要进行一些调整才能使它们与do shell script; <(...)值得注意的是,不支持进程替换( );解决方法是通过<<<"$(...)"必要的额外步骤来准确保留输入中的尾随换行符。
将上述处理程序粘贴到脚本中后,以下是如何将它们应用到命令中的方法:
\n\ndo shell script "sed " & quoted form of \xc2\xac\n ("s/" & my quoteRegex(searchFor) & "/" & my quoteSubst(myData) & "/g") \xc2\xac\n & " " & quoted form of inputFile & " > " & quoted form of outputFile\nRun Code Online (Sandbox Code Playgroud)\n\n至于你原来的症状:
\n\n\n\n\n但奇怪的是,它确实写出了其中包含零数据的文件。
\n
这表明do shell script(a) 能够调用 shell,(b) shell 解析了命令行而没有遇到语法错误;如果满足这些条件,则在命令执行开始之前,输出重定向会> outFile导致目标文件创建为零字节文件,或者如果存在,则将其截断为零字节文件。
如果命令执行失败,则会留下零字节文件。
\n\n\n\n\n我实际上收到此错误:没有这样的文件或目录,退出代码 127
\n
退出代码127表示无法调用作为命令字符串的第一个标记的可执行文件,因为找不到它。
这确实发生了,因为你错误地quoted form of将sed可执行文件名称、它的选项和sed脚本应用在一起,这导致整个结果字符串被解释为可执行文件名称,这显然失败了。
让我们举一个简单的例子:
\n\nquoted form of "sed s/foo/bar/g file"\nRun Code Online (Sandbox Code Playgroud)\n\n产生\'sed s/foo/bar/g file\',包括括起来的单引号。\n将此字符串传递给 shell 会导致 shell 将此字符串视为构成可执行路径或文件名 的单个标记。显然,没有名为sed s/foo/bar/g file存在名为的文件,因此该命令失败。
如上所示,解决方案是将sed、其选项、脚本以及输入文件名和输出文件名作为单独的文件传递标记传递。