Maison >développement back-end >Golang >Outils de ligne de commande avec Go : canalisation des données

Outils de ligne de commande avec Go : canalisation des données

Barbara Streisand
Barbara Streisandoriginal
2024-09-25 06:28:01493parcourir

Command-Line Tools with Go: Piping Data

Unix est bien connu pour prôner la philosophie selon laquelle les commandes doivent faire une chose et bien la faire.

Des opérations sophistiquées de traitement et de transformation de données peuvent souvent être effectuées à l'aide de l'opérateur shell pipe pour enchaîner les commandes afin que la sortie de l'une devienne l'entrée d'une autre, manipulant et transformant les données pour obtenir le résultat souhaité.

Par exemple :

# 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

Avec Go, les programmeurs peuvent créer des commandes efficaces et performantes pour traiter les données. Nous y reviendrons avec les extraits suivants.

Ajouter des numéros de ligne à la sortie

L'essence d'une commande qui peut être utilisée dans une opération de tube est qu'elle lit depuis stdin et écrit sur 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()
}

Cet exemple lit une ligne à la fois depuis stdin et la réécrit sur stdout avec chaque ligne préfixée par le numéro de ligne. Ici, nous utilisons le fichier programme lui-même comme entrée pour générer une sortie numérotée.

$ 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 }

Entrée d'encodage Base64

Cet exemple lit une ligne à la fois depuis stdin, l'encode en base64 et l'écrit sur 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()
}

Étant donné que le scanner se divise en caractères de nouvelle ligne (n) sans les renvoyer, il est nécessaire d'écrire explicitement une nouvelle ligne après avoir écrit chaque ligne.

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

Vous pouvez confirmer que le texte a été correctement encodé en redirigeant le résultat encodé vers la commande système base64 (Linux et MacOS) pour le décoder :

$ 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()
}

Cet article est un extrait d'un court guide d'introduction que j'ai écrit sur les fonctionnalités de bibliothèque standard de Go qui sont utiles pour créer des outils de ligne de commande : Go pour les applications et outils CLI.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn