Eu tenho um cenário em que preciso imprimir uma linha, mas usando um awk if para procurar um número é acrescentado dois pontos duplos com mais números:
Veja abaixo exemplo:
test1 test2 37:375003 test3 test4
test1 test2 38:375004 test3 test4
test1 test2 39:375005 test3 test4
test1 test2 40:375006 test3 test4
test1 test2 41:375007 test3 test4
O que eu quero alcançar é usando o comando como abaixo:
cat test_out.txt | awk "{if ($3 == 37~/\:*/ ) print $0;}"
O acima deve me dar a linha abaixo:
test1 test2 37:375003 test3 test4
Obtendo o erro de sintaxe abaixo:
Syntax Error The source line is 1.
The error context is
{if ( >>> == <<<
awk: 0602-502 The statement cannot be correctly parsed. The source line is 1.
Você precisa usar o
~
operador binário cuja sintaxe é:Para corresponder uma string a uma expressão regular, então:
Para imprimir os registros (
{print}
, abreviação de{print $0}
ação padrão) cujo terceiro campo corresponde ao^37:[[:digit:]]+$
regexp estendido.Na sintaxe ERE:
^
correspondências no início do assunto[...]
: corresponde a qualquer caractere ou elemento de agrupamento no conjunto.[:digit:]
no conjunto acima significa qualquer caractere classificado como dígito decimal na localidade (na maioria dos sistemas, limitado a 0123456789). Altere para0123456789
emmawk
que não suporta essas classes de caracteres POSIX ou se você não deseja corresponder a outros dígitos decimais.0-9
também funcionaria,mawk
mas também poderia corresponder a outros caracteres em algumasawk
implementações.+
é para uma ou mais das coisas anteriores. Então aqui um ou mais dígitos$
correspondências no final do assunto.Se você não se importa se a parte depois
37:
é feita de dígitos ou não, então o regexp é apenas^37:
(37:
no início do assunto).Outra abordagem seria:
Onde a
+ 0
operação numérica forçaawk
a tentar converter$3
para um número, ignorando qualquer coisa além do número inicial. Então isso combinaria com37:anything
, mas também37.0;whatever
¹,3.7e+1
¹, possivelmente0x25#xxx
com algumasawk
implementações,+37+38
... Usando+$3 == 37
embora padrão, não funciona com algumasawk
implementações.Para que o valor (aqui
37
) venha de uma variável do shell, você pode construir o regexp no shell e passá-lo porawk
meio de umaENVIRON
variável ment:Ou faça uma
awk
v
ariável da variável shell²:Evite expandir a variável shell no
awk
código como em:pois isso normalmente introduz vulnerabilidades de injeção de comando (o pior tipo de vulnerabilidade).
Alguns comentários sobre sua tentativa:
$3
que seria expandido para o valor do terceiro argumento para o script de shell e$0
para o nome do script.$3 == 37 ~ /\:*/
.==
tem precedência maior que~
. Então é isso($3 == 37) ~ /\:*/
. Então, isso corresponde ao\:*
regexp com o resultado dessa comparação (1 ou 0, dependendo se$3
é 37 ou não)\:*
como um regexp não é especificado como\:
não é especificado. Para corresponder a um literal:
, ele está:
sozinho.:*
seria 0 ou mais:
s, portanto, corresponda a qualquer coisa, pois qualquer string contém pelo menos 0:
s.*
em regexps corresponde a 0 ou mais da coisa anterior. Você pode estar confundindo com os*
curingas do shell que correspondem a 0 ou mais caracteres. Em regexps, 0 ou mais caracteres são.*
,.
sendo o operador para corresponder a um único caractere.awk
As instruções são da formacondition {action}
, onde tanto a condição quanto a ação podem ser omitidas. No seu caso, você omitiu a condição e usouif
na ação e usou a ação{print $0}
padrão . Enquanto isso funcionar, isso parecerá muito interessante para os usuários.awk
awk
cat
confinarcat
um único arquivo que dificilmente faz sentido. O shell pode abrir o arquivo sozinho para torná-lo o stdin deawk
usar o redirecionamento que salva um processo e a necessidade de empurrar o conteúdo através de um pipe. Você também pode passar o nome do arquivo como argumento para oawk
qual também pode abri-lo sozinho.¹ assumindo que o caractere decimal radix está
.
e não,
no locale, pelo menos com algumasawk
implementações como GNUawk
no modo POSIX.² cuidado com
-v
as barras invertidas, portanto, o usoENVIRON
é mais seguro no caso geral.O primeiro erro é usar aspas duplas
"
para oawk
script que faz o shell expandir$3
para o que o shell tiver, aqui presumivelmente a string vazia. Use aspas simples'
ou um arquivo em vez disso.Então, é claro, use o regex certo para sua tarefa, conforme fornecido em outras respostas.