如何使用 Sys 和 Subprocess 模块以及 Linux Bash 更改部分文件名

问题描述 投票:0回答:8

我有一个Python脚本,它从oldFiles.txt中读取文件名,迭代Linux目录中的文件名,然后使用string.replace更新文件名,最后运行一个子进程来查找这些文件(假设在主目录中)使解释和演示更容易)并使用

更改它们的名称
subprocess.run(['mv', 'oldfile', 'newfile')]

假设我有带有字符串“jane”的文件名,我想将其替换为“jdoe”,文件名示例为: abcd_jane.csv 修改为 abcd_jdoe.csv

sys.argv[1] 是将像下面这样传递的参数

./changeJane.py oldFiles.txt

我正在使用这些空文件进行本地训练,它们的名称保存在oldFiles.txt中

sdafsdfs_jane.doc 12fgdf-jane.csv files_jane.txt

迭代和更新 oldFiles.txt 中的文件名是可以的,或者也可能存在一些错误:-(但我仍然不知道如何运行子进程来实现我的目标,如上所述。这就是我进来的,非常感谢。

PS:我被迫使用 sys 和 subprocess 模块,并且还被迫应用所有提到的细节,这是一项作业评估。

#!/usr/bin/env python3
import sys
import subprocess
with open(sys.argv[1], 'r+') as f:
  for line in f.readlines():
    newline = line.strip()
    newtext = newline.replace("jane", "jdoe")
    subprocess.run(['mv', '~/newline', '~/newtext']) #I know its wrong but this is my limit!

更新

我修改了脚本以返回列表并轻松地迭代其项目,脚本是成功的,但它只进行一次迭代,这意味着它仅应用第一个文件名或第一次迭代,有任何想法可以完成所有迭代并完成工作。非常感谢!!

#!/usr/bin/env python3
import sys
import subprocess
with open(sys.argv[1], 'r') as f:
    content1 = f.readlines()
    content2 = [x.strip() for x in content1]
    content3 = [item.replace("jane", "jdoe") for item in content2]
    for x in content2:
      for i in content3:
        subprocess.run(['mv', '/home/ninja-coder/'+x, '/home/ninja-coder/'+i])
python-3.x bash subprocess sys
8个回答
2
投票

你的第一个代码更简单,你几乎是对的!在第一个代码中没有获得所需输出的原因是因为您没有添加 mv 命令的完整路径

#!/usr/bin/env python3
import sys
import subprocess
f= open (sys.argv[1],"r")
path='/home/<username>'
for line in f.readlines():
 old_name = line.strip()
 new_name = old_name.replace("jane","jdoe")
 subprocess.run(["mv",path+old_name,path+new_name])
f.close()

这对我有用!


1
投票

感谢@Jonatã 和@HackLab 的提示。经过几次尝试,我解决了这个非常烦人的评估,但我学到了很多东西,同样,成功的关键秘诀之一是实践,这是最终的代码

#!/usr/bin/env python3
import sys
import subprocess
with open(sys.argv[1], 'r') as f:
    content1 = f.readlines()
    content2 = [x.strip() for x in content1]
    content3 = [item.replace("jane", "jdoe") for item in content2]
    res = dict(zip(content2, content3))
    for key, value in res.items():
        subprocess.run(['mv', '/home/ninja-coder/'+key, '/home/ninja-coder/'+value])

1
投票

使用嵌套循环在这里不是一个好的做法,也无法达到目的。 使用zip比使用字典

更容易
import sys
import subprocess

from pathlib import Path
with open (sys.argv[1], "r") as f:
    data=[ x.strip() for x in  f.readlines()]
    datanew=[x.replace("jane","jdoe") for x in data]
    for k, t in zip( data,datanew):
      subprocess.run(["mv",'<add path>'+k,'<add path>/+t'])
f.close()

0
投票

使用子进程重命名文件成本太高,而且对您来说工作量太大。使用 Python 本身提供给您的工具重命名该文件。 此外,您不需要打开文件进行写入,只需引用该文件即可迭代该文件:

#!/usr/bin/env python3

import sys
import subprocess

with open(sys.argv[1], 'r') as f:
  for line in f:
    newline = line.strip()
    newtext = newline.replace("jane", "jdoe")
    os.rename(newline, newtext)

0
投票

如果您想更改文件名,我不确定为什么要打开文件。 我认为您想迭代目录中的所有文件,因为您需要 os.listdir() https://www.tutorialspoint.com/python/os_listdir.html

import os

path = "./"

for filename in os.listdir(path):
    newFilename = filename.replace("jane", "jdoe")
    os.rename(path + filename, path + newFilename)

正如 @Poshi 指出的那样,不需要子进程 os.rename 就可以做到这一点 https://www.tutorialspoint.com/python/os_rename.htm

如果你真的想使用子流程

subprocess.run(['mv', path + filename, path + newFilename])

更新

现在是完整的解决方案,我希望能让它更清楚。

#!/usr/bin/env python3
import sys
import subprocess
with open(sys.argv[1], 'r') as f:
    for filename in f.readlines():
        newFilename = filename[:-1].strip().replace("jane", "jdoe")
        subprocess.run(['mv', "~/" + filename[:-1], "~/" + newFilename])

0
投票
#!/usr/bin/env python3

import sys
import subprocess
impotr os

with open(sys.argv[1], 'r') as f:
    for line in f:
        newline = line.strip()
        newtext = newline.replace("jane", "jdoe")
        os.rename(newline, newtext)

0
投票
`
#!/usr/bin/env python3

import sys
import subprocess

with open(sys.argv[1],'r') as f:
        path='/home/student-01-88c93c037e85'
        for filename in f.readlines():
                filename = filename.strip()
                newname = filename.rstrip().replace("jane","jdoe")
                subprocess.run(["mv",path+filename,path+newname])
        f.close()

`
  

0
投票

另一种解决方案:

#!/usr/bin/env python3
import sys
import subprocess
import os

old="jane"
new="jdoe"

with open(sys.argv[1], 'r') as f:
        content = f.readlines()
        result = [(os.path.expanduser('~' + x.strip()), os.path.expanduser('~' + x.strip().replace(old, $
        
        for old_path, new_path in result:
                subprocess.run(['mv',old_path, new_path])
© www.soinside.com 2019 - 2024. All rights reserved.