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.
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.
Respostas:
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.
cut -c
seleciona caracteres; cut -b
ou head -c
seleciona bytes. Isso faz a diferença em alguns locais (na prática, ao usar UTF-8).
cut -c-8
vai selecionar a partir de caráter 1 a 8.
cut
é equivalente no Windows é?
command | dd bs=8 count=1 2>/dev/null
. Não estou dizendo que é mais curto ou superior. Apenas outra alternativa.
cut
, cut -c
funciona assim cut -b
(ou seja, não funciona corretamente para caracteres de vários bytes).
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}
command | sed 's/\(.\{8\}\).*/\1/'
ou se seus suportes sed-lo: command | sed -r 's/(.{8}).*/\1/'
; Caso contrário, +1
head -c
conta bytes , não caracteres. Da mesma forma, entre as principais implementações do Awk, apenas o GNU awk lida com caracteres de vários bytes corretamente - o FreeBSD Awk e o Mawk não.
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 a execução read ... <(command)
, seus caracteres estarão na variável shell REPLY
. Digite help read
para aprender sobre outras opções.
Explicação: o -n8
argumento para read
diz que queremos até 8 caracteres. O -d$'\0'
diz lê 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 -n8 -d$'\0'
é usar -N8
, que lê exatamente 8 caracteres ou até que o stdin atinja o EOF. Nenhum delimitador é respeitado. Provavelmente isso atende melhor às suas necessidades, mas não sei de antemão quantas conchas têm uma leitura que seja honrada, -N
em vez de honrar -n
e -d
. Continuando com a explicação: -r
diz ignore \
-escapes, de modo que, por exemplo, tratamos \\
como dois caracteres, e não como um único \
.
Finalmente, fazemos read ... <(command)
mais do que command | read ...
porque, na segunda forma, a leitura é executada em um subshell que é encerrado imediatamente, 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>
cut
.
read -n <num>
; pequena ressalva: o Bash 3.x (ainda atual no SO) interpreta erroneamente <num>
como uma contagem de bytes e, portanto, falha com caracteres de vários bytes; isso foi corrigido no Bash 4.x.
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
x=8; echo ${word:0:$x}
vez de codificar o número inteiro.
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 criar uma sequência de caracteres de tamanho variável, você 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 uso xxd
:
command | xxd -l$BYTES | xxd -r
Ele gera exatamente $BYTES
bytes, a menos que a command
saída seja mais curta, exatamente essa saída.
cut
a nova linha de fuga é | tr -d '\n'