>  기사  >  백엔드 개발  >  Go의 명령줄 도구: 데이터 파이핑

Go의 명령줄 도구: 데이터 파이핑

Barbara Streisand
Barbara Streisand원래의
2024-09-25 06:28:01450검색

Command-Line Tools with Go: Piping Data

유닉스는 명령이 한 가지 일을 해야 하고 그 일을 잘해야 한다는 철학을 옹호하는 것으로 잘 알려져 있습니다.

복잡한 데이터 처리 및 변환 작업은 종종 셸 파이프 연산자를 사용하여 명령을 연결하여 하나의 출력이 다른 명령의 입력이 되도록 수행하고 데이터를 조작하고 변환하여 원하는 결과를 얻을 수 있습니다.

예:

# Sort file names.
ls | sort

# Count files.
ls -l | count -l

# Print out unique file extensions.
#  1. List all files that have extensions
#  2. Transform the data (discard everything but extensions)
#  3. Sort the list (data must be sorted to identify duplicates)
#  4. Filter out duplicates
#  5. Browse the results
ls *.* | sed 's/.*\.//' | sort | uniq | less

Go를 사용하면 프로그래머는 데이터 처리를 위한 효율적이고 성능이 뛰어난 명령을 만들 수 있습니다. 다음 스니펫을 통해 이에 대해 살펴보겠습니다.

출력에 줄 번호 추가

파이프 작업에 사용할 수 있는 명령의 핵심은 stdin에서 읽고 stdout에 쓰는 것입니다.

add-line-numbers.go

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {

    // Buffered input that splits input on lines.
    input := bufio.NewScanner(os.Stdin)

    // Buffered output.
    output := bufio.NewWriter(os.Stdout)

    lineNo := 0

    // Scan until EOF (no more input).
    for input.Scan() {
        text := input.Text()
        lineNo++
        s := fmt.Sprintf("%03d %s\n", lineNo, text)

        // It would be simpler to just use fmt.Println,
        // but want to emphasize piping stdin to stdout
        // explicitly.
        // Intentionally ignoring return values.
        _, _ = output.WriteString(s)

    }

    // Always explicitly flush remaining buffered output.
    _ = output.Flush()
}

이 예에서는 stdin에서 한 번에 한 줄씩 읽어서 stdout에 다시 씁니다. 각 줄 앞에는 줄 번호가 붙습니다. 여기서는 프로그램 파일 자체를 입력으로 사용하여 번호가 매겨진 출력을 생성합니다.

$ cat add-line-numbers.go | go run add-line-numbers.go
001 package main
002 
003 import (
004     "bufio"
005     "fmt"
006     "os"
007 )
008 
009 func main() {
010 
011     // Buffered input that splits input on lines.
012     input := bufio.NewScanner(os.Stdin)
013 
014     // Buffered output.
015     output := bufio.NewWriter(os.Stdout)
016 
017     lineNo := 0
018 
019     // Scan until EOF (no more input).
020     for input.Scan() {
021         text := input.Text()
022         lineNo++
023         s := fmt.Sprintf("%03d %s\n", lineNo, text)
024 
025         // It would be simpler to just use fmt.Println,
026         // but want to emphasize piping stdin to stdout
027         // explicitly.
028         // Intentionally ignoring return values.
029         _, _ = output.WriteString(s)
030 
031     }
032 
033     // Always explicitly flush remaining buffered output.
034     _ = output.Flush()
035 
036 }

Base64 인코딩 입력

이 예는 stdin에서 한 번에 한 줄씩 읽고, base64로 인코딩한 후 다시 stdout에 씁니다.

package main

import (
    "bufio"
    "encoding/base64"
    "os"
)

func main() {

    // Buffered input that splits input on lines.
    input := bufio.NewScanner(os.Stdin)

    // Base64 Encoder/writer.
    encoder := base64.NewEncoder(
        base64.StdEncoding,
        os.Stdout)

    // Scan until EOF (no more input).
    for input.Scan() {
        bytes := input.Bytes()
        _, _ = encoder.Write(bytes)
        _, _ = encoder.Write([]byte{'\n'})
    }

    // Close the encoder and ensure it flushes remaining output
    _ = encoder.Close()
}

스캐너는 개행 문자(n)를 반환하지 않고 분할하므로 각 줄을 쓴 후 명시적으로 개행 문자를 작성해야 합니다.

$ cat base64-encode.go | go run base64-encode.go
cGFja2FnZSBtYWluCgppbXBvcnQgKAoJImJ1ZmlvIgoJImVuY29kaW5nL2Jhc2U2NCIKCSJvcyIKKQoKZnVuYyBtYWluKCkgewoKCS8vIEJ1ZmZlcmVkIGlucHV0IHRoYXQgc3BsaXRzIGlucHV0IG9uIGxpbmVzLgoJaW5wdXQgOj0gYnVmaW8uTmV3U2Nhbm5lcihvcy5TdGRpbikKCgkvLyBCYXNlNjQgRW5jb2Rlci93cml0ZXIuCgllbmNvZGVyIDo9IGJhc2U2NC5OZXdFbmNvZGVyKAoJCWJhc2U2NC5TdGRFbmNvZGluZywKCQlvcy5TdGRvdXQpCgoJLy8gU2NhbiB1bnRpbCBFT0YgKG5vIG1vcmUgaW5wdXQpLgoJZm9yIGlucHV0LlNjYW4oKSB7CgkJYnl0ZXMgOj0gaW5wdXQuQnl0ZXMoKQoJCV8sIF8gPSBlbmNvZGVyLldyaXRlKGJ5dGVzKQoJCV8sIF8gPSBlbmNvZGVyLldyaXRlKFtdYnl0ZXsnXG4nfSkKCX0KCgkvLyBDbG9zZSB0aGUgZW5jb2RlciBhbmQgZW5zdXJlIGl0IGZsdXNoZXMgcmVtYWluaW5nIG91dHB1dAoJXyA9IGVuY29kZXIuQ2xvc2UoKQp9Cg==

인코딩된 결과를 시스템 base64 명령(Linux 및 MacOS)으로 파이핑하여 디코딩하면 텍스트가 올바르게 인코딩되었는지 확인할 수 있습니다.

$ cat base64-encode.go | go run base64-encode.go | base64 -D
package main

import (
    "bufio"
    "encoding/base64"
    "os"
)

func main() {

    // Buffered input that splits input on lines.
    input := bufio.NewScanner(os.Stdin)

    // Base64 Encoder/writer.
    encoder := base64.NewEncoder(
        base64.StdEncoding,
        os.Stdout)

    // Scan until EOF (no more input).
    for input.Scan() {
        bytes := input.Bytes()
        _, _ = encoder.Write(bytes)
        _, _ = encoder.Write([]byte{'\n'})
    }

    // Close the encoder and ensure it flushes remaining output
    _ = encoder.Close()
}

이 게시물은 명령줄 도구를 만드는 데 유용한 Go의 표준 라이브러리 기능에 관해 제가 작성한 짧은 소개 가이드인 Go for CLI 앱 및 도구에서 발췌한 것입니다.

위 내용은 Go의 명령줄 도구: 데이터 파이핑의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.