Inside a golang program i want to source a file (in this case its .clean
) which would look like this
$HOME/directory1
$HOME/directory1/.directory2
$HOME/directory3
and then run the rm -rf
command before each directory. Does anyone know how to accomplish this?
You can do this using a bufio.Scanner
.
Bold text added by me.
Scanner provides a convenient interface for reading data such as a file of newline-delimited lines of text. Successive calls to the Scan method will step through the 'tokens' of a file, skipping the bytes between the tokens. The specification of a token is defined by a split function of type SplitFunc; the default split function breaks the input into lines with line termination stripped. Split functions are defined in this package for scanning a file into lines, bytes, UTF-8-encoded runes, and space-delimited words. The client may instead provide a custom split function.
Example using os.RemoveAll()
:
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
f, err := os.Open(".clean")
if err != nil {
log.Fatal(err)
}
s := bufio.NewScanner(f)
for s.Scan() {
fmt.Println("Deleting:", s.Text())
if err := os.RemoveAll(s.Text()); err != nil {
log.Println(err)
}
}
if err := s.Err(); err != nil {
log.Fatal(err)
}
}
Or, using Cmd.Run()
from os/exec
to run rm -rf
:
package main
import (
"bufio"
"fmt"
"log"
"os"
"os/exec"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
s := bufio.NewScanner(f)
for s.Scan() {
fmt.Println("Deleting:", s.Text())
cmd := exec.Command("rm", "-rf", s.Text())
if err := cmd.Run(); err != nil {
log.Println(err)
}
}
if err := s.Err(); err != nil {
log.Fatal(err)
}
}
Instead of "sourcing" the file, you could instead just read it:
while IFS= read TARGET; do
rm -fr "${TARGET/'$HOME'/$HOME}"
done < .clean
You can also add checks to it like skipping comments:
while read TARGET; do ## Explicitly do not change IFS to exclude leading and trailing spaces.
case "$TARGET" in
\#*)
# Skip comments.
;;
*)
rm -fr "${TARGET/'$HOME'/$HOME}"
;;
esac
done < .clean
If you need more compatibility i.e. it doesn't support ${PARAM/X/Y}
expansion method, just used sed anyway:
rm -fr "$(echo "$TARGET" | sed "s|\$HOME|$HOME|")" ## No 'g'. I doubt it's sensible to have two `$HOME`'s.