1

「ls」を呼び出し、「s」で終わるファイルの正規表現フィルタリングを介して各行を渡す簡単なプログラムを作成しました。ls は、exec パッケージを学習する目的でのみ使用されます。以下のコードをより正確/簡潔/うまくいくように改善するにはどうすればよいですか?

package main

import (
    "bufio"
    "fmt"
    "os/exec"
    "regexp"
)

func main() {

    cmd := exec.Command("ls")
    stdout, _ := cmd.StdoutPipe()
    s := bufio.NewReader(stdout)
    cmd.Start()

    go cmd.Wait()

    for {
        l, _, err := s.ReadLine()
        if err != nil {
            break
        }

        if m, err := regexp.Match(".*s$", l); m && err == nil {
            fmt.Println(string(l))
        }
    }
}
4

3 に答える 3

3

標準ドキュメントのCmd.Output の例はかなり簡潔です。テキスト処理は行いませんが、コマンドを実行し、1 回の関数呼び出しで出力を取得する方法を示しています。

その例をあなたの例と組み合わせる方法は次のとおりです。

package main

import (
    "bytes"
    "fmt"
    "log"
    "os/exec"
    "regexp"
)

func main() {
    out, err := exec.Command("ls").Output()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Print(string(bytes.Join(regexp.MustCompile(".*s\n").FindAll(out, -1), nil)))
}

パッケージの広範な概要を把握することが目的の場合は、多数の関数とメソッドを試して、それらのさまざまな機能を学習してください。コマンド引数を試してみてください。Cmd 構造体のさまざまなフィールドを試してください。regexp のような他のパッケージに気を取られすぎないようにしてください。パッケージの機能を実行する最も単純な例を探してください。

もちろん、実際のアプリケーションで exec 機能を使用する方法がわかった場合は、試してみてください。その 1 つの機能をさらに詳しく学習します。

于 2012-06-05T17:30:23.137 に答える
2

この種の例では、エラーチェックを追加し、正規表現の使用を停止します。

バッファサイズより大きい入力データの場合、ReadLineは必然的にisPrefixをある時点でtrueに設定して戻ります。ReadString('\ n')は、必要な処理を実行します。バッファに収まるかどうかに関係なく、行末まで読み取り、出力文字列をそのまま拡張します。これは、任意の長さの文字列になってしまう可能性があることも意味します。ReadLine()のプラス面では、行の終わりから「\n」または「\r \ n」が削除されるため、ReadString()を使用する場合は、自分でそれを行う必要があります。

package main

import (
    "bufio"
    "fmt"
    "os/exec"
    "io"
)

func main() {
    var err error
    var out io.Reader

    // Create a command object
    cmd := exec.Command("ls")

    // Obtain a pipe to receive the stdout of the command
    out, err = cmd.StdoutPipe(); if err != nil {
        panic(err)
    }

    // Start the child process
    err = cmd.Start(); if err != nil {
        panic(err)
    }

    // bufio.Reader allows us to read all bytes until newline
    s := bufio.NewReader(out)
    for {
        var line string
        line, err = s.ReadString('\n')
        if err == io.EOF && len(line) == 0 {
            // Good end of file with no partial line
            break
        }
        if err == io.EOF {
            err := fmt.Errorf("Last line not terminated: %q", line)
            panic(err)
        }
        if err != nil {
            panic(err)
        }
        line = line[:len(line)-1]       // drop the '\n'
        if line[len(line)-1] == '\r' {
            line = line[:len(line)-1]   // drop the '\r'
        }
        if line[len(line)-1] == 's' {   // Finally check for lines ending in 's'
            fmt.Println(line)
        }
    }

    // Wait for the result of the command; also closes our end of the pipe
    err = cmd.Wait()
    if err != nil {
        panic(err)
    }
}
于 2012-06-11T14:59:20.263 に答える
0

例えば、

package main

import (
    "bufio"
    "errors"
    "fmt"
    "io"
    "os/exec"
)

func main() {
    cmd := exec.Command("ls")
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        fmt.Println(err)
        return
    }
    ls := bufio.NewReader(stdout)
    err = cmd.Start()
    if err != nil {
        fmt.Println(err)
        return
    }
    for {
        line, isPrefix, err := ls.ReadLine()
        if isPrefix {
            fmt.Println(errors.New("isPrefix: true"))
            return
        }
        if err != nil {
            if err != io.EOF {
                fmt.Println(err)
                return
            }
            break
        }
        fmt.Println(string(line))
    }
    err = cmd.Wait()
    if err != nil {
        fmt.Println(err)
        return
    }
}

出力 (ディレクトリの内容によって異なります):

bench.go
temp.go
于 2012-06-05T15:05:58.830 に答える