Table des matières
Contenu de la question
Ce que j'ai essayé
Solution de contournement
Maison développement back-end Golang Comment lire et formater un flux de texte reçu via un tube bash ?

Comment lire et formater un flux de texte reçu via un tube bash ?

Feb 10, 2024 pm 11:30 PM
overflow bibliothèque standard

如何读取和格式化通过 bash 管道接收的文本流?

Dans notre travail quotidien, nous devons souvent traiter des données textuelles via des outils de ligne de commande. Dans les systèmes Linux, bash pipe (pipe) est un outil très puissant qui peut utiliser la sortie d'une commande comme entrée d'une autre commande. Mais lorsque nous recevons un flux de texte volumineux via un canal, comment pouvons-nous lire et formater efficacement ces données ? Cet article vous présentera quelques conseils et méthodes pratiques pour vous aider à mieux gérer les flux de texte reçus via les tuyaux bash. Que vous soyez débutant ou développeur expérimenté, cet article vous apportera inspiration et aide.

Contenu de la question

Actuellement, j'utilise ce qui suit pour formater les données dans un script npm.

npm run startwin | while ifs= read -r line; do printf '%b\n' "$line"; done | less
Copier après la connexion

Cela fonctionne mais mon collègue n'utilise pas Linux. Donc, je veux implémenter while ifs= read -r line;执行 printf '%bn' "$line";在go中完成 et utiliser le binaire dans le pipeline.

npm run startwin | magical-go-formater
Copier après la connexion

Ce que j'ai essayé

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"
)

func main() {
  fi, _ := os.Stdin.Stat() // get the FileInfo struct

  if (fi.Mode() & os.ModeCharDevice) == 0 {

    bytes, _ := ioutil.ReadAll(os.Stdin)
    str := string(bytes)
    arr := strings.Fields(str)

    for _, v := range arr {
      fmt.Println(v)
    }
}

Copier après la connexion

Actuellement, le programme coupe toutes les sorties du flux de texte.

Solution de contournement

Vous souhaitez utiliser bufio.scanner pour la lecture du type de queue. À mon humble avis, le chèque que vous avez fait sur os.stdin est inutile, mais ymmv.

Voir cette réponse pour un exemple. ioutil.readall() (现已弃用,只需使用 io.readall() )读取错误/eof,但它不是循环输入 - 这就是您需要 bufio.scanner.scan() raisons.

Aussi - %b 将转换文本中的任何转义序列 - 例如传递的行中的任何 n seront tous rendus sous forme de nouvelles lignes - en avez-vous besoin ? b/c go n'a pas de spécificateur de format équivalent, autant que je sache.

Modifier

Donc je pense que vous avez basé le code source de la bibliothèque standard de readall() 的方法将会/可能会起作用......最终。我猜您期望的行为与 bufio.scanner 类似 - 接收进程在写入字节时处理字节(这实际上是一个轮询操作 - 请参阅 scan() pour voir les détails sales) .

Mais avec la version instrumentée de readall() 会缓冲读取的所有内容,并且直到最终出现错误或 eof 才会返回。我破解了 readall() (qui est une copie exacte du code source de la bibliothèque standard, avec juste une petite sortie d'instrumentation supplémentaire), vous pouvez voir qu'elle lit au fur et à mesure que les octets sont écrits, mais elle ne se termine tout simplement pas après le processus d'écriture, il ne renvoie pas et ne produit pas de contenu avant, auquel cas il ferme l'extrémité du tuyau (son descripteur de fichier ouvert), produisant ainsi un eof :

package main

import (
    "fmt"
    "io"
    "os"
    "time"
)

func main() {

    // os.stdin.setreaddeadline(time.now().add(2 * time.second))

    b, err := readall(os.stdin)
    if err != nil {
        fmt.println("error: ", err.error())
    }

    str := string(b)
    fmt.println(str)
}

func readall(r io.reader) ([]byte, error) {
    b := make([]byte, 0, 512)
    i := 0
    for {
        if len(b) == cap(b) {
            // add more capacity (let append pick how much).
            b = append(b, 0)[:len(b)]
        }
        n, err := r.read(b[len(b):cap(b)])

        //fmt.fprintf(os.stderr, "read %d - received: \n%s\n", i, string(b[len(b):cap(b)]))
        fmt.fprintf(os.stderr, "%s read %d - received %d bytes\n", time.now(), i, n)
        i++

        b = b[:len(b)+n]
        if err != nil {
            if err == io.eof {
                fmt.fprintln(os.stderr, "received eof")
                err = nil
            }
            return b, err
        }
    }
}
Copier après la connexion

Je viens d'écrire un script bon marché pour générer des entrées, simuler des tâches de longue durée et n'écrire que périodiquement, j'imagine comment npm se comporterait dans votre cas :

#!/bin/sh

for x in 1 2 3 4 5 6 7 8 9 10
do
  cat ./main.go
  sleep 10
done
Copier après la connexion

BTW, je trouve que la lecture du code de la bibliothèque standard est vraiment utile... ou du moins intéressante dans des cas comme celui-ci.

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 de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le prix du Bitcoin depuis sa naissance 2009-2025 Le résumé le plus complet des prix historiques du BTC Le prix du Bitcoin depuis sa naissance 2009-2025 Le résumé le plus complet des prix historiques du BTC Jan 15, 2025 pm 08:11 PM

Depuis sa création en 2009, Bitcoin est devenu un leader dans le monde des cryptomonnaies et son prix a connu d’énormes fluctuations. Pour fournir un aperçu historique complet, cet article compile les données sur les prix du Bitcoin de 2009 à 2025, couvrant les principaux événements du marché, les changements de sentiment du marché et les facteurs importants influençant les mouvements de prix.

Comment utiliser std :: en C++ Comment utiliser std :: en C++ May 09, 2024 am 03:45 AM

std est l'espace de noms en C++ qui contient les composants de la bibliothèque standard. Pour utiliser std, utilisez l'instruction "using namespace std;". L'utilisation de symboles directement à partir de l'espace de noms std peut simplifier votre code, mais n'est recommandée que lorsque cela est nécessaire pour éviter la pollution de l'espace de noms.

_utilisation complexe en langage C _utilisation complexe en langage C May 08, 2024 pm 01:27 PM

Le type complexe est utilisé pour représenter des nombres complexes en langage C, y compris des parties réelles et imaginaires. Sa forme d'initialisation est complex_number = 3.14 + 2.71i, la partie réelle est accessible via creal(complex_number) et la partie imaginaire est accessible via cimag(complex_number). Ce type prend en charge les opérations mathématiques courantes telles que l'addition, la soustraction, la multiplication, la division et le modulo. De plus, un ensemble de fonctions permettant de travailler avec des nombres complexes est fourni, telles que cpow, csqrt, cexp et csin.

Pointeurs intelligents C++ : une analyse complète de leur cycle de vie Pointeurs intelligents C++ : une analyse complète de leur cycle de vie May 09, 2024 am 11:06 AM

Cycle de vie des pointeurs intelligents C++ : Création : Les pointeurs intelligents sont créés lors de l'allocation de mémoire. Transfert de propriété : Transférer la propriété via une opération de déménagement. Libération : la mémoire est libérée lorsqu'un pointeur intelligent sort de la portée ou est explicitement libéré. Destruction d'objet : lorsque l'objet pointé est détruit, le pointeur intelligent devient un pointeur invalide.

La signification des abdos en langage C La signification des abdos en langage C May 08, 2024 pm 12:18 PM

La fonction abs() en langage C permet de calculer la valeur absolue d'un nombre entier ou à virgule flottante, c'est-à-dire sa distance à zéro, qui est toujours un nombre non négatif. Il prend un argument numérique et renvoie la valeur absolue de ce nombre.

Comment utiliser malloc en langage C Comment utiliser malloc en langage C May 09, 2024 am 11:54 AM

La fonction malloc() en langage C alloue un bloc mémoire dynamique et renvoie un pointeur vers l'adresse de départ. Utilisation : Allouer de la mémoire : malloc(size) alloue un bloc mémoire de la taille spécifiée. Travailler avec la mémoire : accéder et manipuler la mémoire allouée. Libérer la mémoire : free(ptr) libère la mémoire allouée. Avantages : Permet l'allocation dynamique de la mémoire requise et évite les fuites de mémoire. Inconvénients : Le renvoi de NULL en cas d'échec de l'allocation peut entraîner le blocage du programme. Une gestion minutieuse est nécessaire pour éviter les fuites de mémoire et les erreurs.

Le rôle et l'utilisation de strcpy en langage C Le rôle et l'utilisation de strcpy en langage C May 08, 2024 pm 12:42 PM

strcpy est une fonction de bibliothèque standard pour copier des chaînes en langage C. Elle copie la chaîne source dans la chaîne cible et renvoie l'adresse de la chaîne cible. L'utilisation est la suivante : strcpy(char dest, const char src), où dest est l'adresse de la chaîne de destination et src est l'adresse de la chaîne source.

Aperçu du prix historique du Bitcoin depuis sa naissance. Collection complète des tendances historiques des prix du Bitcoin. Aperçu du prix historique du Bitcoin depuis sa naissance. Collection complète des tendances historiques des prix du Bitcoin. Jan 15, 2025 pm 08:14 PM

Le Bitcoin, en tant que crypto-monnaie, a connu une volatilité importante sur le marché depuis sa création. Cet article fournira un aperçu du prix historique du Bitcoin depuis sa naissance pour aider les lecteurs à comprendre ses tendances de prix et ses moments clés. En analysant les données historiques sur les prix du Bitcoin, nous pouvons comprendre l'évaluation de sa valeur par le marché, les facteurs affectant ses fluctuations et fournir une base pour les décisions d'investissement futures.

See all articles