Se eu tenho uma saída muito longa de um comando (linha única), mas sei que só quero os primeiros [x] (digamos 8) caracteres da saída, qual é a maneira mais fácil de conseguir isso? Não há delimitadores.
Uma maneira é usar cut
:
command | cut -c1-8
Isso fornecerá os 8 primeiros caracteres de cada linha de saída. Como cut
faz parte do POSIX, é provável que esteja na maioria dos Unices.
Existem outras maneiras de obter apenas os 8 primeiros caracteres.
command | head -c8
command | awk '{print substr($0,1,8);exit}'
command | sed 's/^\(........\).*/\1/;q'
E se você tiver festança
var=$(command)
echo ${var:0:8}
Outra solução de um liner usando expansão de parâmetro
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
Se você tiver um Shell suficientemente avançado (por exemplo, o seguinte funcionará no Bash, não tenho certeza sobre o traço), você pode:
read -n8 -d$'\0' -r <(command)
Após executar read ... <(command)
, seus caracteres estarão na variável Shell REPLY
. Digite help read
Para aprender sobre outras opções.
Explicação: o argumento -n8
Para read
diz que queremos até 8 caracteres. O -d$'\0'
Diz ler até um nulo, em vez de uma nova linha. Dessa forma, a leitura continuará com 8 caracteres, mesmo que um dos caracteres anteriores seja uma nova linha (mas não se for nulo). Uma alternativa para -n8 -d$'\0'
É usar -N8
, Que lê exatamente 8 caracteres ou até que o stdin atinja o EOF. Nenhum delimitador é respeitado. Isso provavelmente se encaixa melhor às suas necessidades, mas não sei de antemão quantas conchas têm uma leitura que homenageia -N
Em vez de homenagear -n
E -d
. Continuando com a explicação: -r
Diz ignorar \
- escapa, de modo que, por exemplo, tratamos \\
Como dois caracteres, e não como um único \
.
Finalmente, fazemos read ... <(command)
em vez de command | read ...
Porque, na segunda forma, a leitura é executada em um subshell que é imediatamente encerrado, perdendo as informações que você acabou de ler.
Outra opção é fazer todo o processamento dentro do subshell. Por exemplo:
$ echo abcdefghijklm | { read -n8 -d$'\0' -r; printf "REPLY=<%s>\n" "$REPLY"; }
REPLY=<abcdefgh>
Isso é portátil:
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
Para construir uma sequência de caracteres de comprimento variável, tem sua própria pergunta aqui .
Eu tive esse problema ao gerar manualmente arquivos de soma de verificação no repositório maven. Infelizmente cut -c
sempre imprime uma nova linha no final da saída. Para suprimir que eu use xxd
:
command | xxd -l$BYTES | xxd -r
Ele gera exatamente $BYTES
bytes, a menos que a saída de command
seja mais curta, exatamente essa saída.