Подпроцесс с Python 3.8 и Linux Bash - PullRequest
0 голосов
/ 11 июля 2020

У меня есть сценарий Python, который считывает имена файлов из oldFiles.txt, перебирает имена файлов, которые являются файлами в каталоге Linux, затем обновляет имена файлов с помощью string.replace и, наконец, запускает подпроцесс, чтобы найти эти файлы (скажем, в домашнем каталоге, чтобы упростить объяснение и демонстрацию) и измените их имена, используя

subprocess.run(['mv', 'oldfile', 'newfile')]

. Предположим, у меня есть имена файлов со строкой «jane», и я хочу заменить ее на «jdoe», пример имени файла будет: abcd_jane.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!

UPDATE

Я изменил скрипт на вернуть список и удобно перебирать его элементы, сценарий успешен, но он выполняет только одну итерацию, что означает, что он применяет только первое имя файла или первую итерацию, любые идеи для выполнения всех итераций и завершает sh задание. Большое спасибо !!

#!/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])

Ответы [ 4 ]

1 голос
/ 20 июля 2020

Ваш первый код проще, и вы почти правы! Причина, по которой вы не получаете требуемый вывод в первом коде, заключается в том, что вы не добавили полный путь к команде 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()

У меня это сработало!

0 голосов
/ 11 июля 2020

Я не уверен, почему вы хотите открыть файл, если хотите изменить имя файла. Я думаю, вы хотите перебрать все файлы в каталоге, для чего вам нужен 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. переименование должно сделать это https://www.tutorialspoint.com/python/os_rename.htm

Если вы действительно хотите использовать подпроцесс

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

UPDATE

Вот теперь полное решение, надеюсь, что делает понятнее.

#!/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 голосов
/ 12 июля 2020

Спасибо @ 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])
0 голосов
/ 11 июля 2020

Использование подпроцесса для переименования файла слишком дорого и слишком трудоемко для вас. Переименуйте файл с помощью инструментов, которые предлагает вам сам 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...