可递归
思维导图:递归部分
package Createfile import ( "fmt" "log" "os" "os/exec" "time" ) func cmddir(dir string) { //创建文件夹命令 cmd := exec.Command("mkdir",dir) if _,err := cmd.CombinedOutput();err !=nil{ log.Println(err) } } func exist(dir string) { //检查文件/文件夹状态,go中如果文件/文件夹存在是不会判定为错误的所以err会为空 f,err := os.Stat(dir) if err == nil{ //判定是不是目录 if f.IsDir(){ //是,什么都不做就返回 return }else{ cmddir(dir) } } //err不为空如果isnotexist判定为真那么就是不存在 if os.IsNotExist(err){ cmddir(dir) } } func CreateFile(dir string) *os.File{ exist(dir) //拼接日志文件文件名字 osfile,err := os.OpenFile(dir + "/getUrl.log" + fmt.Sprintf("-%d-%d-%d.log", time.Now().Year(), time.Now().Month(), time.Now().Day(), ),os.O_CREATE|os.O_WRONLY|os.O_APPEND,0644) if err != nil{ log.Println(err) } //返回文件指针因为写入后要关闭但是写入不在这个函数中,不关闭会存在资源泄露严重会导致宕机 return osfile }
package Readfile import ( "io/ioutil" "log" ) func ReadFile(filename string) []byte { //很简单,读取文件内容并返回内容 fileByte,fileErr := ioutil.ReadFile(filename) if fileErr != nil { log.Println(fileErr) } return fileByte }
package Treelist import ( "fmt" "io/ioutil" "path" ) //这个是存储文件路径的切片可以理解为一组路径集合 var FileSlice []string func Recursion(dir string) { //读取目录并不包含子目录 files, errRead := ioutil.ReadDir(dir) if errRead != nil { fmt.Println(errRead) } //把上面读取的files便利因为读取后是个切片,需要逐一判断,如果是目录就拼接路径后接着便利 for _, file := range files { if file.IsDir() { filename := file.Name() path := dir + filename + "/" //递归 Recursion(path) }else { //不是就读取文件名字包含后缀,然后拼接成路径存在最开始定义的切片中 filename := path.Base(file.Name()) pwd := dir + filename FileSlice = append(FileSlice, pwd) } } }
package UrlGet import ( "fmt" "littletools/GetUrl/Createfile" . "littletools/GetUrl/Readfile" "log" "mvdan.cc/xurls/v2" "regexp" ) func UrlGet(filename string) { file := Createfile.CreateFile("OutPut") defer file.Close() //获取url,获取的值是切片 arrayByte := xurls.Relaxed().FindAll(ReadFile(filename), -1) //便利k是索引也就是第几个,v就是索要的url for k, v := range arrayByte { //https/http开头的留下 if match,err := regexp.MatchString(`^(https://){1}|^(http://){1} `,string(v));match{ if err!=nil{ log.Println(err) } //根据上述条件继续判断如果是要去除的fqdn那么就跳过进行下一条的判断,否则就存到文件中 if matchGov,errGov := regexp.MatchString(`(去除的fqdn){1}`,string(v));matchGov{ if errGov != nil{ log.Println(errGov) } continue } file.WriteString(fmt.Sprintf(" %s %d %s\n",filename, k, v)) } } }
package main import ( "fmt" "littletools/GetUrl/Treelist" "littletools/GetUrl/UrlGet" "os" "sync" ) //同样为了并发安全不然会出现没执行完毕就退出的问题 var wg sync.WaitGroup //给写入文件加锁,不然会发生并发不安全 var lock sync.Mutex func main() { if arg_num := len(os.Args[1:]);arg_num < 1{ fmt.Println("Waring:请输入路径的名称") return } for _, v := range os.Args[1:] { dir := v + "/" Treelist.Recursion(dir) } for _, v := range Treelist.FileSlice { wg.Add(1) go func(filepath string) { lock.Lock() defer wg.Done() defer lock.Unlock() UrlGet.UrlGet(filepath) }(v) } //等待所有线程结束后推出 wg.Wait() }
测试目录结构
删除正则二次筛选结果会包含不要的正则部分
加上二次筛选结果不会包含不要的正则部分
纯个人手写思维,转载请注明出处,感谢。
我同意我亦师亦友的话,凭什么,别人十几年的积累你一招就能学会。所以我希望踏实的人能看我的博客有收获,同和我一样的小白一起进步,GO长期不定时更新。
一个不聪明的话痨运维(~^o^~)
针对,生活我不是想赢。我只是不想输!