gpt4 book ai didi

go - 无法使用 filepath.Walk() 重命名给定路径中的所有目录

转载 作者:IT王子 更新时间:2023-10-29 02:32:01 24 4
gpt4 key购买 nike

这是我的访问函数,

func visit(path string, f os.FileInfo, err error) error {
if !f.IsDir() {
return nil
}
str := path
if str == config.Path {
return nil
}
if str == config.LatestPath {
return nil
}
dir := str
dir = strings.TrimPrefix(str, filepath.Dir("C:\\Users\\Mark\\Desktop\\testfolder\\"))
slashes := strings.Count(dir, "\\")
if slashes < config.PrevSlashes {
x := len(config.Slashes) - 1
for x > slashes {
config.Slashes[x] = 0
x--
}
}
config.Slashes[slashes]++
config.PrevSlashes = slashes
prename := ""
for k, v := range config.Slashes {
if k != 0 {
if k <= slashes {
prename += strconv.Itoa(v) + "."
}
}
}
fmt.Println(config.Slashes)
myRegex := `(\\(?P<number>[\d\.]*)) \w`
for i := 0; i < slashes-1; i++ {
myRegex += `(\\(?P<number` + strconv.Itoa(i) + `>[\d\.]*)) \w*`
}
re := regexp.MustCompile(myRegex)
for i, match := range re.FindAllString(dir, -1) {
return nil
fmt.Println(i, match)
}
Cdir := filepath.Dir(path)
newpath := fmt.Sprintf("%s\\%s %s", Cdir, prename, f.Name())
config.LatestPath = path
os.Rename(path, newpath)
return nil
}

文件夹结构是这样的

testfolder\a\aa\aaa, 
testfolder\a\aa\aab,
testfolder\a\aa\aac,
testfolder\a\ab\aaa

我遇到的问题是文件路径,Walk() 看不到更改后的目录名称。

它首先将 testfolder\a\aa\aaa 重命名为 testfolder\1。 a\aa\aaa 然后尝试将 testfolder\a\aa\aaa 重命名为 testfolder\a\1。 aa\aaa 但我希望它重命名 testfolder\1。 a\aa\aaa 到测试文件夹\1。\1.1。 aa\aaa

最终结果应该是这样的

\testfolder\1. a\1.1. aa\1.1.1. aaa
\testfolder\1. a\1.1. aa\1.1.2. aab
\testfolder\1. a\1.1. aa\1.1.3. aac
\testfolder\1. a\1.2. ab\1.2.1. aaa
\testfolder\1. a\1.2. ab\1.2.2. aab
\testfolder\2. b\2.1. aa\2.1.1. aaa
\testfolder\2. b\2.1. aa\2.2.2. aab

简单地说我想命名一个目录“x.name”和其中的文件夹“x.x.name”,其中x是一个数字

编辑 1:我通过计算路径名并将它们放入数组中然后在 filepath.Walk() 函数完成后重命名目录来解决这个问题

func visit(path string, f os.FileInfo, err error) (error) {
if err != nil {
log.Fatal(err)
}
if !f.IsDir() {
return nil
}
str := path
if str == config.Path {
return nil
}
dir := str
dir = strings.TrimPrefix(str, filepath.Dir("C:\\Users\\Mark\\Desktop\\testfolder\\"))
slashes := strings.Count(dir, "\\")
if slashes < config.PrevSlashes {
x := len(config.Slashes) - 1
for x > slashes {
config.Slashes[x] = 0
x--
}
}
config.Slashes[slashes]++
config.PrevSlashes = slashes
prename := ""
for k, v := range config.Slashes {
if k != 0 {
if k <= slashes {
prename += strconv.Itoa(v) + "."
}
}
}
myRegex := `(\\(?P<number>[\d\.]*)) \w`
for i := 0; i < slashes-1; i++ {
myRegex += `(\\(?P<number` + strconv.Itoa(i) + `>[\d\.]*)) \w*`
}
re := regexp.MustCompile(myRegex)
for i, match := range re.FindAllString(dir, -1) {
config.Dirpaths[slashes] = fmt.Sprintf("%s", f.Name())
return nil
fmt.Println(i, match)
}
config.Dirpaths[slashes] = fmt.Sprintf("%s %s", prename, f.Name())
prenameOld := ""
for k, v := range config.Dirpaths {
if k != 0 {
if v != "" {
if k == slashes {
break
}
prenameOld += v + "\\"
}
}
}
oldname := strings.TrimRight(config.Path+prenameOld+f.Name(), "\\")
newName := strings.TrimRight(config.Path+prenameOld+config.Dirpaths[slashes], "\\")
if len(config.OldNames) != config.MaxDir {
config.OldNames = append(config.OldNames, oldname)
config.NewNames = append(config.NewNames, newName)
}
return nil
}

最佳答案

如果您查看 source对于 filepath.Walk,您会看到它执行以下操作:

  • 获取当前目录的名称排序列表
  • 对于每个名字:
    • 调用你的回调函数
    • 调用 walk(name)

对于给定的目录,testfolder 中的第一个调用将针对 testfolder/a,因为 testfolder/1 尚不存在。

无论您做什么,Walk 都不会重新读取 testfolder/,因此它永远不会看到新的 1。一个子目录。

Walk 期间重命名目录/文件是获得错误行为的好方法。相反,我建议您自己列出目录中的文件并进行自己的递归。

类似的东西:

  • 选择下一个 dir 进行处理(默认为 testfolder)
  • 使用File.ReadDirNames 读取dir 的当前子目录/文件
  • 对于每个条目:
    • 根据需要重命名
    • 将新名称添加到要处理的目录列表

这使用迭代。或者,您可以递归新名称(这是 filepath.Walk 失败的地方,因为它不知道新名称)。

关于go - 无法使用 filepath.Walk() 重命名给定路径中的所有目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48206327/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com