Afferrare i primi [x] caratteri per una stringa da una pipe


Risposte:


82

Un modo è usare cut:

 command | cut -c1-8

Questo ti darà i primi 8 caratteri di ogni riga di output. Poiché cutfa parte di POSIX, è probabile che sia presente nella maggior parte degli Unices.


3
Nota che cut -cseleziona i caratteri; cut -bo head -cseleziona i byte. Ciò fa la differenza in alcune versioni locali (in pratica, quando si utilizza UTF-8).
Gilles 'SO- smetti di essere malvagio'

Inoltre, non è necessario specificare l'indice iniziale in questo caso. Dicendo cut -c-8selezionerà dal personaggio 1 a 8.
Sparhawk

@Steven, cutl'equivalente su Windows è?
Pacerier,

Inoltre command | dd bs=8 count=1 2>/dev/null. Non dire che è più corto o superiore. Solo un'altra alternativa.
dubiousjim,

@Gilles, ma nota che con le versioni correnti di GNU cut, cut -cfunziona come cut -b(cioè, non funziona correttamente per i caratteri multi-byte).
Stéphane Chazelas,

24

Questi sono altri modi per ottenere solo i primi 8 caratteri.

command | head -c8

command | awk '{print substr($0,1,8);exit}' 

command | sed 's/^\(........\).*/\1/;q'

E se hai bash

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

2
Penso che la seguente formulazione sed è un po 'più facile da leggere: command | sed 's/\(.\{8\}\).*/\1/'o se i supporti sed IT: command | sed -r 's/(.{8}).*/\1/'; Altrimenti, +1
Steven D

Roba buona, ma nota che head -cconta i byte , non i caratteri. Allo stesso modo, tra le principali implementazioni di Awk, solo GNU awk gestisce correttamente i caratteri multibyte - FreeBSD Awk e Mawk no.
mklement0

2

Se si dispone di una shell sufficientemente avanzata (ad esempio, in Bash funzionerà quanto segue, non si è sicuri del trattino), è possibile eseguire:

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

Dopo l'esecuzione read ... <(command), i tuoi personaggi saranno nella variabile shell REPLY. Digita help readper conoscere altre opzioni.

Spiegazione: l' -n8argomento per readdire che vogliamo fino a 8 caratteri. Il -d$'\0'dice letto fino a un null, piuttosto che a una nuova riga. In questo modo la lettura continuerà per 8 caratteri anche se uno dei caratteri precedenti è una nuova riga (ma non se è un valore nullo). Un'alternativa -n8 -d$'\0'è usare -N8, che legge esattamente 8 caratteri o fino a quando lo stdin non raggiunge EOF. Nessun delimitatore è onorato. Questo probabilmente si adatta meglio alle tue esigenze, ma non so con certezza quante shell hanno una lettura che onora -Ninvece di onorare -ne -d. Continuando con la spiegazione: -rdice ignore \-escapes, in modo che, per esempio, trattiamo \\come due caratteri, piuttosto che come un singolo \.

Infine, lo facciamo read ... <(command)piuttosto che command | read ...perché nella seconda forma, la lettura viene eseguita in una subshell che viene quindi immediatamente chiusa, perdendo le informazioni che hai appena letto.

Un'altra opzione è eseguire tutta l'elaborazione all'interno della subshell. Per esempio:

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

1
Se vuoi solo generare 8 caratteri e non hai bisogno di elaborarli nella shell, usa semplicemente cut.
dubiousjim,

Buono a sapersi read -n <num>; piccolo avvertimento: Bash 3.x (ancora corrente su SO) interpreta erroneamente <num>un conteggio di byte e quindi fallisce con caratteri multi-byte; questo è stato risolto in Bash 4.x.
mklement0

Questa è una risposta grande e utile. Molto più generale degli altri.
not2qubit

2

Un'altra soluzione di rivestimento utilizzando l' espansione dei parametri

echo ${word:0:x}

EG: word="Hello world"
echo ${word:0:3} or echo ${word::3} 
o/p: Hel


EG.2: word="Hello world"
echo ${word:1:3}
o/p: ell

Puoi anche usare una variabile che ne trattiene la lunghezza, ad esempio: x=8; echo ${word:0:$x}invece di codificare per intero il numero intero.
Cometsong,

1

Questo è portatile:

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

Costruire una stringa di lunghezza variabile di caratteri ha una sua domanda qui .


0

Ho avuto questo problema durante la generazione manuale dei file di checksum nel repository Maven. Sfortunatamente cut -cstampa sempre una nuova riga alla fine dell'output. Per sopprimere che io uso xxd:

command | xxd -l$BYTES | xxd -r

Emette esattamente $BYTESbyte, a meno che l' commandoutput non sia più breve, quindi esattamente quell'output.


un altro metodo per decollare cutla nuova riga finale è il pip in:| tr -d '\n'
Cometsong
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.