Saisir les premiers caractères d'une string à partir d'un tube

Si j'ai une sortie vraiment longue d'une command (ligne simple), mais je sais que je veux seulement les premiers [x] (disons 8) caractères de la sortie, quelle est la façon la plus facile d'get cela? Il n'y a pas de délimiteurs.

Une façon est d'utiliser la cut :

  command | cut -c1-8 

Cela vous donnera les 8 premiers caractères de chaque ligne de sortie. Étant donné que la cut fait partie de POSIX, il est susceptible d'être sur la plupart des Unices.

Voici quelques autres façons d'get uniquement les 8 premiers caractères.

 command | head -c8 command | awk '{print substr($0,1,8);exit}' command | sed 's/^\(........\).*/\1/;q' 

Et si vous avez bash

 var=$(command) echo ${var:0:8} 

Si vous avez un shell suffisamment avancé (par exemple, ce qui suit fonctionnera dans Bash, pas sûr de tiret), vous pouvez faire:

 read -n8 -d$'\0' -r <(command) 

Après l'exécution de read ... <(command) , vos caractères seront dans la variable shell REPLY . Tapez help read pour en savoir plus sur les autres options.

Explication: l'argument -n8 à read indique que nous voulons avoir jusqu'à 8 caractères. Le -d$'\0' dit lire jusqu'à un null, plutôt qu'à une nouvelle ligne. De cette façon, la lecture se poursuivra pour 8 caractères même si l'un des caractères antérieurs est une nouvelle ligne (mais pas si c'est une valeur nulle). Une alternative à -n8 -d$'\0' est d'utiliser -N8 , qui lit exactement 8 caractères ou jusqu'à ce que le stdin atteigne EOF. Aucun délimiteur n'est honoré. Cela répond probablement mieux à vos besoins, mais je ne sais pas combien de coquilles ont une lecture qui honore -N plutôt que d'honorer -n et -d . En continuant avec l'explication: -r dit ignorer \ -escapes, de sorte que, par exemple, nous considérons \\ comme deux caractères, plutôt que comme un seul \ .

Enfin, nous read ... <(command) plutôt que la command | read ... command | read ... parce que dans la seconde forme, la lecture est exécutée dans un sous-shell qui est alors immédiatement quitté, perdant les informations que vous venez de lire.

Une autre option est de faire tout votre traitement à l'intérieur du sous-shell. Par exemple:

 $ echo abcdefghijklm | { read -n8 -d$'\0' -r; printf "REPLY=<%s>\n" "$REPLY"; } REPLY=<abcdefgh> 

C'est portable:

 a="$(command)" # Get the output of the command. b="????" # as many ? as characters are needed. echo ${a%"${a#${b}}"} # select that many chars from $a 

Pour build une string de longueur variable de caractères a sa propre question ici .

J'ai eu ce problème lors de la génération manuelle des files checksum dans le référentiel maven. Malheureusement, cut -c toujours une nouvelle ligne à la fin de la sortie. Pour supprimer que j'utilise xxd :

 command | xxd -l$BYTES | xxd -r 

Il sort exactement $BYTES octets, sauf si la sortie de la command est plus courte, alors exactement cette sortie.