如何在macOS快捷指令中向Python脚本传递多个输入?
如何在macOS快捷指令中向Python脚本传递多个输入?
我完全懂你的感受——原本用Python批量替换文本挺顺手,但想通过Mac快捷指令加个简单UI却卡在传参上,这确实让人挠头!毕竟不是程序员,对着报错信息真的很懵。看你截图里的快捷指令设置,思路是对的,问题主要出在Python脚本怎么接收输入,以及快捷指令怎么正确传参上。咱们一步步来解决这个问题,两种简单的方法任你选,都能让你顺利把三个输入传给脚本。
你之前的快捷指令大概是这样的对吧?
方法一:通过「标准输入」传递(更稳定,推荐)
这种方法把三个输入内容用一个特殊的“分隔符”拼在一起,传给Python脚本,脚本再自动拆分出三个部分,完全避免Shell解析特殊字符的麻烦(比如换行、引号这些,用命令行参数很容易出问题)。
第一步:修改你的Python脚本
把原来的脚本替换成下面的代码(直接复制粘贴就行,原来的替换逻辑我帮你完整保留了):
import sys def main(): # 从快捷指令读取所有输入内容 all_input = sys.stdin.read() # 用一个特殊字符串分割成三个部分(这个分隔符别和你输入的内容重复就行,比如下面这个) separator = "===我的专属分隔符===" parts = all_input.split(separator, 2) # 检查是不是刚好拆分成了三个部分 if len(parts) != 3: print("输入格式不对哦,请确保三个输入都正确传递了") return # 把拆分后的内容赋值给原来的变量,和你原来的脚本逻辑无缝衔接 text_passage, to_replace_input, replacements_input = parts # 下面是你原来的批量替换逻辑,不用改! to_replace = [line.strip() for line in to_replace_input.split('\n') if line.strip()] replacements = [line.strip() for line in replacements_input.split('\n') if line.strip()] if len(to_replace) != len(replacements): print("待替换的内容和替换后的内容数量不匹配,请检查") return # 执行批量替换 result = text_passage for old_str, new_str in zip(to_replace, replacements): result = result.replace(old_str, new_str) # 输出结果,这样快捷指令里就能直接拿到处理后的文本啦 print(result) if __name__ == "__main__": main()
第二步:设置你的macOS快捷指令
按照下面的步骤一步步来,别漏了任何一项:
- 打开「快捷指令」APP,新建一个快捷指令
- 第一个动作:询问输入,设置提示文本为「请输入要处理的原始文本」,输入类型选「多行文本」(这样能保留你输入的换行符)
- 第二个动作:设定变量,把刚才的输入保存为「原始文本」(变量名随便取,只要自己能识别就行)
- 第三个动作:询问输入,提示文本「请输入待替换的字符串(每行一个)」,输入类型选「多行文本」
- 第四个动作:设定变量,保存为「待替换列表」
- 第五个动作:询问输入,提示文本「请输入对应的替换字符串(每行一个)」,输入类型选「多行文本」
- 第六个动作:设定变量,保存为「替换列表」
- 第七个动作:文本,点击输入框,把三个变量按顺序拼起来:
原始文本+===我的专属分隔符===+待替换列表+===我的专属分隔符===+替换列表(注意分隔符要和脚本里的完全一样,一个字符都不能改) - 第八个动作:运行Shell脚本
- 脚本内容:
/usr/bin/python3 "/你的脚本保存绝对路径/你的脚本名.py"(先在终端里输入which python3找到你的Python路径,替换掉前面的/usr/bin/python3;脚本路径要写绝对路径,比如/Users/你的用户名/Documents/批量替换脚本.py) - 「传递输入」选项选择「通过标准输入」
- 「Shell」选默认的
/bin/zsh就行
- 脚本内容:
做完这些,运行快捷指令试试——输入三个内容,就能直接拿到处理后的文本啦!
方法二:通过命令行参数传递(适合文本内容不复杂的情况)
如果你的输入里没有太多奇怪的特殊字符(比如引号、反斜杠、复杂的符号),也可以用命令行参数的方式,步骤更简单一点:
第一步:修改Python脚本
import sys def main(): # 检查是不是传了三个参数过来 if len(sys.argv) != 4: print("需要传入三个内容:原始文本、待替换列表、替换列表") return # 从命令行参数里拿到三个输入内容 text_passage = sys.argv[1] to_replace_input = sys.argv[2] replacements_input = sys.argv[3] # 下面是你原来的替换逻辑,完全不用改 to_replace = [line.strip() for line in to_replace_input.split('\n') if line.strip()] replacements = [line.strip() for line in replacements_input.split('\n') if line.strip()] if len(to_replace) != len(replacements): print("待替换和替换内容的数量不匹配哦,请检查") return result = text_passage for old_str, new_str in zip(to_replace, replacements): result = result.replace(old_str, new_str) # 输出处理后的结果 print(result) if __name__ == "__main__": main()
第二步:设置快捷指令
- 前面同样是三个「询问输入」+「设定变量」的动作,和方法一一样
- 「运行Shell脚本」的内容改成:
/usr/bin/python3 "/你的脚本绝对路径.py" "$1" "$2" "$3"(同样要替换成你的Python路径和脚本路径) - 「传递输入」选择「作为参数传递」
- 把之前保存的三个变量(原始文本、待替换列表、替换列表)都拖到「运行Shell脚本」的输入区域里,这样
$1就对应第一个输入,$2对应第二个,$3对应第三个
常见坑点提醒(一定要注意!)
- Python路径要写绝对路径:别直接写
python3,不然可能因为快捷指令的环境变量问题找不到Python。在终端输入which python3就能拿到你的Python绝对路径,比如/opt/homebrew/bin/python3 - 分隔符别和输入内容重复:方法一里的分隔符一定要用一个你输入内容里绝对不会出现的字符串,比如上面的
===我的专属分隔符===,不然脚本会拆分错误 - 多行文本要选对输入类型:「询问输入」的输入类型必须选「多行文本」,不然你输入的换行符会丢失,导致待替换和替换的列表不能正确按行分割
这样改完,应该就能彻底解决你之前的输入传递错误问题啦!
备注:内容来源于stack exchange,提问作者Crabgrass0899





