16
|
1 /*
|
|
2 little unix tool library.
|
|
3 */
|
|
4 package lu
|
|
5
|
|
6 import (
|
|
7 "archive/tar"
|
|
8 "bufio"
|
|
9 "bytes"
|
|
10 "compress/gzip"
|
|
11 "crypto/md5"
|
|
12 "crypto/sha256"
|
|
13 "fmt"
|
|
14 "io"
|
|
15 "log"
|
|
16 "os"
|
|
17 "os/exec"
|
|
18 "path/filepath"
|
|
19 "strings"
|
|
20 )
|
|
21
|
|
22 func CmdTime( cmdline string ) {
|
|
23 cmd := exec.Command( "ls", "-l" )
|
|
24 cmd.Stdin = strings.NewReader( "some input" )
|
|
25 var out bytes.Buffer
|
|
26 cmd.Stdout = &out
|
|
27 err := cmd.Run()
|
|
28 if err != nil {
|
|
29 log.Fatal( err )
|
|
30 }
|
|
31 fmt.Printf( "%q\n", out.String() )
|
|
32 }
|
|
33
|
|
34 /* cut -d, -f: */
|
|
35 func CutCsv( files []string, cols []string ) {
|
|
36 }
|
|
37
|
|
38 /* cat -n: done. */
|
|
39 func Cat_n( files []string ) {
|
|
40 if len( files ) == 0 {
|
|
41 cnt := 1
|
|
42 input := bufio.NewScanner( os.Stdin )
|
|
43 for input.Scan() {
|
|
44 fmt.Printf( "%5d %s\n", cnt, input.Text() )
|
|
45 cnt++
|
|
46 }
|
|
47 } else {
|
|
48 for _, file := range files {
|
|
49 cnt := 1
|
|
50 f, _ := os.Open( file )
|
|
51 input := bufio.NewScanner( f )
|
|
52 for input.Scan() {
|
|
53 fmt.Printf( "%5d %s\n", cnt, input.Text() )
|
|
54 cnt++
|
|
55 }
|
|
56 f.Close()
|
|
57 }
|
|
58 }
|
|
59 }
|
|
60
|
|
61 /* wc -l: done. */
|
|
62 func Wc_l( files []string ) {
|
|
63 if len( files ) == 0 {
|
|
64 cnt := 0
|
|
65 input := bufio.NewScanner( os.Stdin )
|
|
66 for input.Scan() {
|
|
67 cnt++
|
|
68 }
|
|
69 fmt.Printf( "%d\n", cnt )
|
|
70 } else {
|
|
71 for _, file := range files {
|
|
72 cnt := 0
|
|
73 f, _ := os.Open( file )
|
|
74 input := bufio.NewScanner( f )
|
|
75 for input.Scan() {
|
|
76 cnt++
|
|
77 }
|
|
78 f.Close()
|
|
79 fmt.Printf( "%s:\t%5d\n", file, cnt )
|
|
80 }
|
|
81 }
|
|
82 }
|
|
83
|
17
|
84 /* tar cvfz: done. */
|
|
85 func Tgz( tgzfile string, files []string ) {
|
|
86
|
|
87 tgz, err := os.Create( tgzfile )
|
|
88 if err != nil {
|
|
89 log.Fatal( err )
|
|
90 }
|
|
91 defer tgz.Close()
|
|
92
|
|
93 gw := gzip.NewWriter( tgz )
|
|
94 defer gw.Close()
|
|
95 tw := tar.NewWriter( gw )
|
|
96 defer tw.Close()
|
|
97
|
|
98 for _, file := range fullpath( files ) {
|
|
99 f, err := os.Open( file )
|
|
100 if err != nil {
|
|
101 log.Fatal( err )
|
|
102 }
|
|
103
|
|
104 stat, _ := f.Stat()
|
|
105 header := new( tar.Header )
|
|
106 header.Name = file
|
|
107 header.Size = stat.Size()
|
|
108 header.Mode = int64( stat.Mode() )
|
|
109 header.ModTime = stat.ModTime()
|
|
110
|
|
111 if err := tw.WriteHeader( header ); err != nil {
|
|
112 log.Fatal( err )
|
|
113 }
|
|
114 if _, err := io.Copy( tw, f ); err != nil {
|
|
115 log.Fatal( err )
|
|
116 }
|
|
117 f.Close()
|
|
118 }
|
|
119 }
|
|
120
|
16
|
121 /* tar xvfz: done. */
|
|
122 func UnTgz( files []string ) {
|
|
123
|
|
124 for _, file := range files {
|
|
125
|
|
126 f, err := os.Open( file )
|
|
127 if err != nil {
|
|
128 log.Fatal( err )
|
|
129 }
|
|
130 zr, err := gzip.NewReader( f )
|
|
131 if err != nil {
|
|
132 log.Fatal( err )
|
|
133 }
|
|
134
|
|
135 tr := tar.NewReader( zr )
|
|
136
|
|
137 for {
|
|
138 hdr, err := tr.Next()
|
|
139 if err == io.EOF {
|
|
140 break // End of archive
|
|
141 }
|
|
142 if err != nil {
|
|
143 log.Fatal( err )
|
|
144 }
|
|
145 fmt.Printf( "%s\n", hdr.Name )
|
|
146
|
|
147 dir := filepath.Dir( hdr.Name )
|
|
148 if ( dir != "" ) {
|
|
149 os.MkdirAll( dir, 0744 )
|
|
150 }
|
|
151 f, err := os.OpenFile( hdr.Name, os.O_RDWR|os.O_CREATE, 0644 )
|
|
152 if err != nil {
|
|
153 log.Fatal( err )
|
|
154 }
|
|
155 if _, err := io.Copy( f, tr ); err != nil {
|
|
156 log.Fatal( err )
|
|
157 }
|
|
158
|
|
159 if err := f.Close(); err != nil {
|
|
160 log.Fatal( err )
|
|
161 }
|
|
162 }
|
|
163
|
|
164 if err := zr.Close(); err != nil {
|
|
165 log.Fatal( err )
|
|
166 }
|
|
167 }
|
17
|
168 }
|
16
|
169
|
17
|
170 func fullpath( files []string ) []string {
|
|
171 var buf []string
|
|
172 for _, f := range files {
|
|
173 fi, _ := os.Stat( f )
|
|
174 if fi.IsDir() {
|
|
175 filepath.Walk( f, func( path string, info os.FileInfo, err error ) error {
|
|
176 if !info.IsDir() {
|
|
177 buf = append( buf, path )
|
|
178 }
|
|
179 return nil
|
|
180 } )
|
|
181 } else {
|
|
182 buf = append( buf, f )
|
|
183 }
|
|
184 }
|
|
185 return buf
|
16
|
186 }
|
|
187
|
|
188 /* tac: done. */
|
|
189 func Reverse( files []string ) {
|
|
190 var buf []string
|
|
191 if len( files ) == 0 {
|
|
192 input := bufio.NewScanner( os.Stdin )
|
|
193 for input.Scan() {
|
|
194 buf = append( buf, input.Text() )
|
|
195 }
|
|
196 } else {
|
|
197 for _, file := range files {
|
|
198 f, _ := os.Open( file )
|
|
199 input := bufio.NewScanner( f )
|
|
200 for input.Scan() {
|
|
201 buf = append( buf, input.Text() )
|
|
202 }
|
|
203 f.Close()
|
|
204 }
|
|
205 }
|
|
206 for i := len( buf ); i > 0; i-- {
|
|
207 fmt.Println( buf[i-1] )
|
|
208 }
|
|
209 }
|
|
210
|
|
211 func Grep( word string, inv bool, files []string ) {
|
|
212 if len( files ) == 0 {
|
|
213 fmt.Println("grep stdin")
|
|
214 } else {
|
|
215 fmt.Println("grep")
|
|
216 }
|
|
217 }
|
|
218
|
|
219 /* uniq: done. */
|
|
220 func Uniq( cnt, dup bool, files []string ) {
|
|
221 var lines []string
|
|
222 lcnt := make( map[string]int )
|
|
223 lpnt := make( map[string]bool )
|
|
224
|
|
225 if len( files ) == 0 {
|
|
226 input := bufio.NewScanner( os.Stdin )
|
|
227 for input.Scan() {
|
|
228 lines = append( lines, input.Text() )
|
|
229 lcnt[ input.Text() ]++
|
|
230 }
|
|
231 } else {
|
|
232 for _, file := range files {
|
|
233 f, _ := os.Open( file )
|
|
234 input := bufio.NewScanner( f )
|
|
235 for input.Scan() {
|
|
236 lines = append( lines, input.Text() )
|
|
237 lcnt[ input.Text() ]++
|
|
238 }
|
|
239 f.Close()
|
|
240 }
|
|
241 }
|
|
242
|
|
243 for _, line := range lines {
|
|
244 if !lpnt[ line ] {
|
|
245 if dup && lcnt[ line ] == 1 {
|
|
246 continue
|
|
247 }
|
|
248 if cnt {
|
|
249 fmt.Printf( "%5d ,", lcnt[ line ] )
|
|
250 }
|
|
251 fmt.Printf( "%s\n", line )
|
|
252 lpnt[ line ] = true
|
|
253 }
|
|
254 }
|
|
255 }
|
|
256
|
|
257 func Head( n int, files []string ) {
|
|
258 if n > 0 {
|
|
259 if len( files ) == 0 {
|
|
260 input := bufio.NewScanner( os.Stdin )
|
|
261 for input.Scan() {
|
|
262 fmt.Println( input.Text() )
|
|
263 n--
|
|
264 if n == 0 {
|
|
265 return
|
|
266 }
|
|
267 }
|
|
268 } else {
|
|
269 for _, file := range files {
|
|
270 if n == 0 {
|
|
271 return
|
|
272 }
|
|
273 f, _ := os.Open( file )
|
|
274 input := bufio.NewScanner( f )
|
|
275 for input.Scan() {
|
|
276 fmt.Println( input.Text() )
|
|
277 n--
|
|
278 if n == 0 {
|
|
279 break
|
|
280 }
|
|
281 }
|
|
282 f.Close()
|
|
283 }
|
|
284 }
|
|
285 } else {
|
|
286 if len( files ) == 0 {
|
|
287
|
|
288 } else {
|
|
289
|
|
290 }
|
|
291 }
|
|
292 }
|
|
293
|
|
294 /* replace: */
|
|
295 func Replace( s, t string, files []string ) {
|
|
296 if len( files ) == 0 {
|
|
297 input := bufio.NewScanner( os.Stdin )
|
|
298 for input.Scan() {
|
|
299 }
|
|
300 } else {
|
|
301 for _, file := range files {
|
|
302 f, _ := os.Open( file )
|
|
303 input := bufio.NewScanner( f )
|
|
304 for input.Scan() {
|
|
305 }
|
|
306 f.Close()
|
|
307 }
|
|
308 }
|
|
309 }
|
|
310
|
|
311 /* touch: */
|
|
312 func Touch( files []string ) {
|
|
313 for _, file := range files {
|
|
314 f, _ := os.Open( file )
|
|
315 f.Close()
|
|
316 }
|
|
317 }
|
|
318
|
|
319 /* md5: done. */
|
|
320 func Md5( files []string ) {
|
|
321 for _, file := range files {
|
|
322 f, _ := os.Open( file )
|
|
323 h := md5.New()
|
|
324 if _, err := io.Copy( h, f ); err != nil {
|
|
325 log.Fatal( err )
|
|
326 }
|
|
327 f.Close()
|
|
328 if len( files ) == 1 {
|
|
329 fmt.Printf( "%x\n", h.Sum( nil ) )
|
|
330 } else {
|
|
331 fmt.Printf( "%s:\t%x\n", file, h.Sum( nil ) )
|
|
332 }
|
|
333 }
|
|
334 }
|
|
335
|
|
336 /* sha256: done. */
|
|
337 func Sha256( files []string ) {
|
|
338 for _, file := range files {
|
|
339 f, _ := os.Open( file )
|
|
340 h := sha256.New()
|
|
341 if _, err := io.Copy( h, f ); err != nil {
|
|
342 log.Fatal( err )
|
|
343 }
|
|
344 f.Close()
|
|
345 if len( files ) == 1 {
|
|
346 fmt.Printf( "%x\n", h.Sum( nil ) )
|
|
347 } else {
|
|
348 fmt.Printf( "%s:\t%x\n", file, h.Sum( nil ) )
|
|
349 }
|
|
350 }
|
|
351 }
|
|
352
|