Então, eu tenho uma linha:
ID: 54376
Você pode me ajudar a criar uma regex que só retornaria números sem "ID:"?
NOTA: Essa sequência está em um arquivo.
Então, eu tenho uma linha:
ID: 54376
Você pode me ajudar a criar uma regex que só retornaria números sem "ID:"?
NOTA: Essa sequência está em um arquivo.
Respostas:
Tente o seguinte:
grep -oP '(?<=ID: )[0-9]+' file
ou:
perl -nle 'print $1 if /ID:.*?(\d+)/' file
-o
e -P
são extensões GNU para grep
. -o
trabalha com os BSDs também. O suporte ao PCRE -P
nem sempre é compilado.
Use egrep
com -o
ou grep
com a -Eo
opção para obter apenas o segmento correspondente. Use [0-9]
como regex para obter apenas números:
grep -Eo [0-9]+ filename
Existem muitas maneiras de fazer isso. Por exemplo:
Use o GNU grep
com PCREs recentes e combine os números depois de ID:
:
grep -oP 'ID:\s*\K\d+' file
Use awk
e simplesmente imprima o último campo de todas as linhas que começam comID:
awk '/^ID:/{print $NF}' file
Isso também imprimirá campos que não são números, para obter apenas números e apenas no segundo campo, use
awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
Use o GNU grep com expressões regulares estendidas e analise-o duas vezes:
grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
\K
está fazendo no primeiro exemplo?
-o
para imprimir apenas a parte correspondente, mas também as coisas de descarte Eu não estou interessado em comparar. echo "foobar" | grep -oP "foobar"
Eecho "foobar" | grep -oP 'foo\Kbar'
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'
Isso imprimirá apenas todos os números e espaços que ocorrerem depois ID: 54376
em qualquer entrada de arquivo.
Acabei de atualizar o item acima um pouco para torná-lo um pouco mais rápido *
e não criar p
linhas em branco após remover os caracteres não {numéricos, espaço}.
Ele aborda linhas de regex /ID: 54376/
,
através do $
passado e sobre eles s///
remove todos ou quaisquer *
caracteres ^
não [^ 0-9]*
em seguida, p
rints /
qualquer /
linha com um .
carácter restante.
{
echo line
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'
54376
1 03 2
3 03 4
5 03 6
7 03 8
9 03 10
54376
Usando sed:
{
echo "ID: 1"
echo "Line doesn't start with ID: "
echo "ID: Non-numbers"
echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'
O -n
é "não imprime nada por padrão", o /^ID: [0-9][0-9]*$/
é "para linhas que correspondem a este regex" (começa com "ID:", depois 1 ou mais dígitos e, em seguida, fim de linha), e o s/ID: //p
é do formulário s/pattern/repl/flags
- s
significa que está substituindo, para substituir o padrão "ID: "
pelo texto de substituição ""
(sequência vazia) usando a p
bandeira, o que significa "imprima esta linha depois de fazer a substituição".
Resultado:
1
4
Outro comando GNU sed,
sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file
Imprime qualquer número após ID:
+
. Se a diferença entre um personagem e 3 caracteres é o seu script pode não funcionar em todos sed
s você provavelmente deve fazer: sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'
. Sua resposta também perde a primeira ID: [0-9]
em uma linha contendo duas ocorrências de ID: [0-9]
.
Use grep + awk:
grep "^ID" your_file | awk {'print $2'}
Bônus: fácil de ler :)
grep
se estiver usando awk
. awk '/^ID/ { print $2 }'
faz a mesma coisa e evita problemas de buffer de linha grep . Também é praticamente o mesmo que uma das soluções na resposta do @ terdon.