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

  • 本文关键字:路径 Walk go in 文件 重命名 go
  • 更新时间 :
  • 英文 :


这是我的访问函数,

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
}

文件夹结构如下所示

testfolderaaaaaa, 
testfolderaaaaab, 
testfolderaaaaac, 
testfolderaabaaa

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

它首先将 TestFolder\a\aa\aaa 重命名为 TestFolder\1。 a\aa\aaa,然后尝试将 testfolder\a\aa\aaa 重命名为 testfolder\a\a\1。 aa\a 但我希望它将 testfolder\1. a\aa\aaa 重命名为 testfolder\1。 a\1.1. aa\aaa

最终结果应如下所示

testfolder1. a1.1. aa1.1.1. aaa
testfolder1. a1.1. aa1.1.2. aab
testfolder1. a1.1. aa1.1.3. aac
testfolder1. a1.2. ab1.2.1. aaa
testfolder1. a1.2. ab1.2.2. aab
testfolder2. b2.1. aa2.1.1. aaa
testfolder2. b2.1. aa2.2.2. aab

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

编辑 1:我通过计算路径名并将其放入数组中,然后在文件路径之后重命名目录来解决此问题。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
}

如果您查看filepath.Walk的源代码,您会发现它执行以下操作:

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

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

无论你做什么,Walk都不会重读testfolder/,所以它永远不会看到新的1. a子目录。

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

大致如下:

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

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

最新更新