python 如何将一个文件夹里面的文件重新命名并复制到另外一个文件夹下

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 如何将一个文件夹里面的文件重新命名并复制到另外一个文件夹下相关的知识,希望对你有一定的参考价值。

A文件夹里面有一些列名称为a_out.pdbqt, a1_out.pdbqt, b_out.pdbqt...的文件,如何编写python脚本实现把A文件夹里面的这些文件命名为a.pdbqt, a1.pdbqt, b.pdbqt...(去掉名称后面的_out)。并把这些文件放入到B文件夹下面

import shutil
shutil.copy("oldfile","newfile")

用这个代码,把文件名对应改下就可以了

追问

关键是A文件夹里面有一大批文件,不是一个文件,这个命令只能复制一个文件

追答

先遍历一遍文件夹,把里面的文件路径都放到一个列表里面,在用for循环里shutil.copy

import os
file_list = os.listdir(folder_A)

file_list里面就是folder_A下面的所有文件/文件夹名了,不过不是绝对路径,你要想加上绝对路径,得自己配置,用下面的代码

new_path = os.path.join(path,x)

参考技术A #!/usr/bin/env python
# -*- coding:utf-8 -*-

import os
rootdirA = os.getcwd()+os.sep+'A'+os.sep
rootdirB = os.getcwd()+os.sep+'B'+os.sep
cmd =  'copy %s%s %s%s'

for parent,dirnames,filenames in os.walk(rootdirA):    #遍历a文件夹所有文件
    for filename in filenames:
        #print filename+'===>'+filename.replace('_out','')
        new_file = filename.replace('_out','')
        print rootdirA,filename,rootdirB,new_file
        tmp = cmd%(rootdirA,filename,rootdirB,new_file)
        os.system(tmp)

追问

出现错误了,这个该怎么解决?
/home/a_out.pdbqt /home/a.pdbqt
sh: copy: command not found

本回答被提问者和网友采纳

在fsnotify上递归重新生成文件删除/重命名(Golang)

目标:

我正在尝试监视可能随时被移动或删除的文件。如果是,我想重新生成此文件,以便应用程序可以继续写入它。

尝试:

我试图通过实现两个函数monitorFile()来监听fsnotify事件,并通过一个通道将删除的文件名发送到listen(),在通过未缓冲的通道mvrm(移动或重命名)接收到文件路径字符串后,将递归地重新生成文件。

观察到的行为:

我可以echo 'foo' >> ./inlogs/test.log并看到写通知,甚至可以rm ./inlogs/test.log(或mv),并看到该文件重新生成...但只有一次。如果我第二次rmmv文件,则不会重新生成该文件。

  • 奇怪的是,在本地Mac OSx(系统版本:macOS 10.13.2(17C88),内核版本:Darwin 17.3.0)上不会发生意外行为,但是在具有构建的两台不同Linux机器上会发生这种情况:

Linux 3.13.0-32-generic#57-Ubuntu SMP x86_64 x86_64 x86_64 GNU / Linux

Linux 4.9.51-10.52.amzn1.x86_64#1 SMP x86_64 x86_64 x86_64 GNU / Linux

诊断尝试:

不同的行为让我觉得我有竞争条件。然而,go build -race没有输出。

我想知道done chan是否因为这样的竞争条件而接收?

抱歉这不是“可以游乐场”的,但任何建议或观察这可能是由于racy或buggy欢迎。

watcher.go:

package main

import (
    "os"
    "log"
    "fmt"

    "github.com/go-fsnotify/fsnotify"
)

//Globals
var mvrm chan string

func main() {
    mvrm = make(chan string)
    listen(mvrm)
    monitorFile("./inlogs/test.log", mvrm)
}

func listen(mvrm chan string) {
    go func() {
        for {
            select {
            case fileName := <-mvrm :
                fmt.Println(fileName)
                newFile, err := os.OpenFile(fileName, os.O_RDWR | os.O_CREATE | os.O_APPEND , 0666)
                if err == nil {
                    defer newFile.Close()

                    // Recursively re-spawn monitoring
                    go listen(mvrm)
                    go monitorFile(fileName, mvrm)
                } else {
                    log.Fatal("Err re-spawning file")
                }
            default:
                continue
            }
        }
    }()
}

func monitorFile(filepath string, mvrm chan string) {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    done := make(chan bool)
    go func() {
        for {
            select {
            case event := <-watcher.Events:
                switch event.Op {
                case fsnotify.Write :
                    log.Println("Write!")
                    continue
                case fsnotify.Chmod :
                    log.Println("Chmod!")
                    continue
                case fsnotify.Remove, fsnotify.Rename :
                    log.Println("Moved or Deleted!")
                    mvrm <- event.Name
                    continue
                default:
                    log.Printf("Unknown: %v
", event.Op)
                    continue
                }
            case err := <-watcher.Errors:
                log.Println("Error:", err)
            }
        }
    }()

    err = watcher.Add(filepath)
    if err != nil {
        log.Fatal(err)
    }
    <-done
}

编辑:

通过一些很好的反馈,我把它配对了。在Linux中,它现在按照预期重新生成文件,但在使用top进行监视后,我发现每次移动或删除文件时它都会产生一个新的PID,所以我仍然有泄漏。关于如何消除这种行为的建议欢迎。

https://play.golang.org/p/FrlkktoK2-s

答案

请参阅代码注释,代码注释中的大部分讨论。

https://play.golang.com/p/qxq58h1nQjp

在golang宇宙之外,但facebook有一个工具可以完成你所寻找的东西,只是没有那么多代码乐趣:):https://github.com/facebook/watchman

package main

import (
    "log"
    "os"

    // couldn't find the go-fsnotify, this is what pops up on github
    "github.com/fsnotify/fsnotify"
)

func main() {
    monitorFile("./inlogs/test.log")
}

func monitorFile(filepath string) {

    // starting watcher
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    // monitor events
    go func() {
        for {
            select {
            case event := <-watcher.Events:
                switch event.Op {
                case fsnotify.Create:
                    log.Println("Created")

                case fsnotify.Write:
                    log.Println("Write")

                case fsnotify.Chmod:
                    log.Println("Chmod")

                case fsnotify.Remove, fsnotify.Rename:
                    log.Println("Moved or Deleted")

                    respawnFile(event.Name)

                    // add the file back to watcher, since it is removed from it
                    // when file is moved or deleted
                    log.Printf("add to watcher file:  %s
", filepath)
                    // add appears to be concurrently safe so calling from multiple go routines is ok
                    err = watcher.Add(filepath)
                    if err != nil {
                        log.Fatal(err)
                    }

                    // there is  not need to break the loop
                    // we just continue waiting for events from the same watcher

                }
            case err := <-watcher.Errors:
                log.Println("Error:", err)
            }
        }
    }()

    // add file to the watcher first time
    log.Printf("add to watcher 1st: %s
", filepath)
    err = watcher.Add(filepath)
    if err != nil {
        log.Fatal(err)
    }

    // to keep waiting forever, to prevent main exit
    // this is to replace the done channel
    select {}
}

func respawnFile(filepath string) {
    log.Printf("re creating file %s
", filepath)

    // you just need the os.Create()
    respawned, err := os.Create(filepath)
    if err != nil {
        log.Fatalf("Err re-spawning file: %v", filepath)
    }
    defer respawned.Close()

    // there is no need to call monitorFile again, it never returns
    // the call to "go monitorFile(filepath)" was causing another go routine leak
}

玩得开心!

另一答案

我没有足够的声誉来评论,所以我会假装这是一个答案。

在Linux上,fsnotify使用inotify监视fs更改,这意味着调用每个add将运行一个系统调用来创建一个新进程,这就是为什么你看到它产生PID的原因。

如果这对您来说是个问题,那么通常的做法是监视文件的目录并过滤与之相关的事件。这意味着更少的系统调用,但更多的代码。自己挑选吧。

以上是关于python 如何将一个文件夹里面的文件重新命名并复制到另外一个文件夹下的主要内容,如果未能解决你的问题,请参考以下文章

IDEAjava文件重新命名

JAVA 使文件件里面的所有文件重命名新文件名(求源代码)

Python:如何将csv文件某一列中所有相同元素的行分别另外以要求的命名格式保存

Python:如何将csv文件某一列中所有相同元素的行分别另外以要求的命名格式保存

如何创建python文件

在fsnotify上递归重新生成文件删除/重命名(Golang)