parent
f3423e3b85
commit
a878df3603
@ -0,0 +1,2 @@ |
|||||||
|
tr |
||||||
|
tr.exe |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
|
||||||
|
|
||||||
|
build: |
||||||
|
go build .
|
||||||
@ -0,0 +1,100 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"flag" |
||||||
|
"os" |
||||||
|
"bufio" |
||||||
|
"strings" |
||||||
|
"fmt" |
||||||
|
"log" |
||||||
|
) |
||||||
|
|
||||||
|
type Opts struct { |
||||||
|
Compliment bool |
||||||
|
Delete bool |
||||||
|
Squeeze bool |
||||||
|
Truncate bool |
||||||
|
} |
||||||
|
|
||||||
|
type Translator struct { |
||||||
|
opts Opts |
||||||
|
TwoArgs bool |
||||||
|
RuneMap map[rune]rune |
||||||
|
} |
||||||
|
|
||||||
|
func (tr *Translator) ParseOpts() { |
||||||
|
var from []rune |
||||||
|
var to []rune |
||||||
|
tr.RuneMap = make(map[rune]rune) |
||||||
|
tr.TwoArgs = true |
||||||
|
|
||||||
|
flag.BoolVar(&tr.opts.Compliment, "c", false, "Use compliment of array1") |
||||||
|
flag.BoolVar(&tr.opts.Delete, "d", false, "Delete chars in array1") |
||||||
|
flag.BoolVar(&tr.opts.Squeeze, "s", false, "Squeeze chars in array2") |
||||||
|
flag.BoolVar(&tr.opts.Truncate, "t", false, "Truncate array1 to array2 length") |
||||||
|
flag.Parse() |
||||||
|
|
||||||
|
args := flag.Args() |
||||||
|
|
||||||
|
if flag.NArg() == 1 { |
||||||
|
from, to = []rune(args[0]), []rune(args[0]) |
||||||
|
tr.TwoArgs = false |
||||||
|
} else if flag.NArg() == 2 { |
||||||
|
from, to = []rune(args[0]), []rune(args[1]) |
||||||
|
} else { |
||||||
|
log.Fatal("USAGE: tr [-c] [-d] [-s] [-t] <array1> [array2]") |
||||||
|
} |
||||||
|
|
||||||
|
for i, ch := range from { |
||||||
|
tr.RuneMap[ch] = to[i] |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (tr *Translator) Translate(from rune) rune { |
||||||
|
if !tr.TwoArgs { log.Fatal("translate requires two args") } |
||||||
|
|
||||||
|
to, ok := tr.RuneMap[from] |
||||||
|
|
||||||
|
if ok { |
||||||
|
return to |
||||||
|
} else { |
||||||
|
return from |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (tr *Translator) Delete(line string) string { |
||||||
|
result := make([]rune, 0, len(line)) |
||||||
|
|
||||||
|
for _, ch := range []rune(line) { |
||||||
|
_, ok := tr.RuneMap[ch] |
||||||
|
|
||||||
|
if !ok { |
||||||
|
result = append(result, ch) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return string(result) |
||||||
|
} |
||||||
|
|
||||||
|
func (tr *Translator) Process(line string) { |
||||||
|
if tr.opts.Delete { |
||||||
|
line = tr.Delete(line) |
||||||
|
} else { |
||||||
|
line = strings.Map(tr.Translate, line) |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Print(line) |
||||||
|
} |
||||||
|
|
||||||
|
func main() { |
||||||
|
tr := new(Translator) |
||||||
|
tr.ParseOpts() |
||||||
|
|
||||||
|
scan := bufio.NewScanner(os.Stdin) |
||||||
|
|
||||||
|
for scan.Scan() { |
||||||
|
line := scan.Text() + "\n" |
||||||
|
|
||||||
|
tr.Process(line) |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue