在 Windows 平台上的 Anaconda 中从 Python 替换 Perl

Posted

技术标签:

【中文标题】在 Windows 平台上的 Anaconda 中从 Python 替换 Perl【英文标题】:Perl substitution from Python in Anaconda on Windows platform 【发布时间】:2021-11-10 01:48:27 【问题描述】:

在 Windows 上安装 perl、m2-base 和其他一些软件包的 Anaconda shell 环境中:

$ echo "/" > junk
$ more junk
"/"
$ perl -pi.bak -e "s/\"\/\"/\"\\\\\"/" junk
$ more junk junk.bak
::::::::::::::
junk
::::::::::::::
"\"
::::::::::::::
junk.bak
::::::::::::::
"/"

我想在 Python 中复制它。我的脚本是这样的:

import subprocess
cmd = 'perl -pi.bak -e "s/\"\/\"/\"\\\\\"/" junk'
subprocess.call(cmd, shell = True)

给出以下输出:

$python test_perl.py
Substitution replacement not terminated at -e line 1.

我尝试了不同的反斜杠组合、不同的引号样式以及在 perl 中使用不同的分隔符(即用类似@ 的东西替换/),但似乎无法弄清楚如何破解这个难题.

更新

subprocess.call(['perl', '-pi.bak', '-e', "s!\\\"\/\"!\"\\\\\\\"!", 'junk'], shell = True) 有效,但我很困惑为什么subprocess 不需要额外的引号来封装 perl switch 语句。任何见解将不胜感激。

--

有关我实际在做什么的更多信息,我正在尝试在我的 Windows 平台上的 Anaconda 环境中安装一个专为 Linux/Unix 设计的 Python 模块。一方面,我需要在模块的某些文件中将“/”替换为“\”。我知道我可以直接编辑文件并使用os.path.split 之类的东西,而不仅仅是split("/"),但我正在尝试创建一个可以完成所有工作的文件,因此只需克隆 git 存储库并运行设置脚本。

【问题讨论】:

从您的代码看来,在文件中您尝试将"/" 替换为"\"。您参考 Unix/Linux 编写的 Python 模块,您尝试在 Windows 中使用该模块。好吧,听起来您尝试在路径字符串中替换 目录/文件分隔符。如果是这样,则路径不包括每个目录/文件分隔符周围的"。也许您需要以一种更清楚地揭示问题的方式来描述您的问题。 从 Python 脚本中调用 Perl 来进行如此简单的替换有点奇怪。为什么不使用 Python 的强大功能在没有 Perl 帮助的情况下进行这样的更改? Perl 不是 Windows 的组成部分。您是否建议要克隆您的 git 存储库,用户必须安装 Perl 才能使用该模块? @Polar Bear - 好问题。 Python 模块很乱,包装了一大堆来自不同来源的 f90 代码,并使用一大堆嵌套的 Makefile 下载文件并在编译前更改内容。这都是在构建模块本身之前。我想确保我写的东西清楚地遵循了 Makefile,所以我没有用原生 Python 重写 Makefile,而是使用subprocess 调用重新构建它们。 【参考方案1】:

按照 python 演示代码模拟 perl -i.bak ... 行为。

问题描述没有解释为什么 OP 求助于 Perl 来进行简单的替换,并将 .bak 文件保留为备份副本。

Python 有足够的肌肉来执行这样的操作,只需几行代码。

import os

ext_bak  = '.bak'
file_in  = 'path_substitute.txt'
file_bak = file_in + ext_bak

# remove backup file if exists
if os.path.exists(file_bak):
    os.remove(file_bak)

# rename original file to backup
os.rename(file_in,file_bak);

f = open(file_bak,'r')  # read from backup file
o = open(file_in, 'w')  # write to a file with original name

for line in f:
    o.write(line.replace('/','\\'))    # replace / with \ and write

# close files
f.close()
o.close()

输入path_substitute.txt

some path /opt/pkg/dir_1/file_1 word_1
other path /opt/pkg/dir_2/file_2 word_2
one more /opt/pkg/dir_3/file_3 word_3

输出path_substitute.txt

some path \opt\pkg\dir_1\file_1 word_1
other path \opt\pkg\dir_2\file_2 word_2
one more \opt\pkg\dir_3\file_3 word_3

【讨论】:

同意,正如您所说,Python 具有 muscle,并且我同意您不需要使用 Perl。我更想知道为什么subprocess 调用没有达到我的预期,而不是弄清楚如何进行切换,所以这是我没有正确解释的原因。

以上是关于在 Windows 平台上的 Anaconda 中从 Python 替换 Perl的主要内容,如果未能解决你的问题,请参考以下文章

Windows 10 上的 anaconda cythonize C++

python学习指南—Windows 平台下载安装 Anaconda 及 Python 虚拟环境创建

python学习指南—Windows 平台下载安装 Anaconda 及 Python 虚拟环境创建

python学习指南—Windows 平台下载安装 Anaconda 及 Python 虚拟环境创建

如何在 Windows 上的 Anaconda Python 中安装 Keras 和 Theano?

在Windows 7上运行的Anaconda上的TensorFlow