这是我的访问函数,
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
失败的地方,因为它不知道新名称)。