-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloopit.go
107 lines (100 loc) · 2.34 KB
/
loopit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"bufio"
"flag"
"fmt"
"os"
"os/exec"
"regexp"
"runtime"
"strconv"
"sync"
"time"
)
type Job struct {
Start time.Time
Cmd string
}
func main() {
numCPU := runtime.NumCPU()
runtime.GOMAXPROCS(numCPU)
cmd := flag.String("c", "", "Command to execute. Use MYFILE1 or MYFILE2 as wildcards")
file1 := flag.String("f1", "", "First file to loop through")
file2 := flag.String("f2", "", "Second file to loop through")
pretend := flag.Bool("p", false, "Pretend. List commands that would have been run.")
multi := flag.Int("n", 1, "number of simultaneous commands")
flag.Parse()
if *multi > numCPU {
*multi = numCPU
}
list1, err := readLines(*file1)
check(err)
list2 := []string{"null"}
if *file2 != "" {
list2, err = readLines(*file2)
check(err)
}
re1 := regexp.MustCompile("MYFILE1")
re2 := regexp.MustCompile("MYFILE2")
job := regexp.MustCompile("MYJOB")
cmdChan := make(chan Job)
var wg sync.WaitGroup
if !*pretend {
for i := 0; i < *multi; i++ {
wg.Add(1)
go executeCmd(cmdChan, &wg)
}
}
start := time.Now()
jobsStarted := 0
jobsTotal := len(list1) * len(list2)
for _, f1 := range list1 {
for _, f2 := range list2 {
jobsStarted++
jobNum := strconv.Itoa(jobsStarted)
out := job.ReplaceAllString(re1.ReplaceAllString(re2.ReplaceAllString(*cmd, f2), f1), jobNum)
if *pretend {
fmt.Println(out)
} else {
cmd := Job{Start: time.Now(), Cmd: out}
cmdChan <- cmd
fmt.Printf("Job %d of %d started\n", jobsStarted, jobsTotal)
fmt.Println("Time elapsed since start ", time.Since(start))
}
}
}
close(cmdChan)
wg.Wait()
fmt.Println("Finished at:", time.Now())
fmt.Println("Elapsed time:", time.Since(start))
}
func executeCmd(cmdChan chan Job, wg *sync.WaitGroup) {
for cmd1 := range cmdChan {
// fmt.Println("starting command: ", cmd1)
// args := strings.Split(cmd1, " ")
cmd := exec.Command("sh", "-c", cmd1.Cmd) //use the shell to interpret the command
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
}
wg.Done()
}
func readLines(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}
func check(err error) {
if err != nil {
panic(err)
}
}