Difícil grep. Como posso isolar esse número?

1

Eu tenho este conteúdo de arquivo:

  63 41,3,11,12 
  1 31,60,72,96 
  7 41,3,31,14,15,68,59,60 
  7 60,72,96 
  7 60 
  1 41,3,31,31,14,15,68,59,60 
  60 41,3,115,12,13,66,96 
  1 41,3,11,12,13,66,96 

Preciso usar o '7' antes do '60' (onde o '60' não é seguido por '72, 96 ').

    
por Uxio 26.07.2018 / 14:17

4 respostas

4

Amostra modificada com base nos comentários

$ cat ip.txt
  7 60,72,96 
  7 60 
3 601
 2 60,72,962
5 60,3
43 60   
3 52360

$ grep -oP '^\h*\K\d+(?=\h+60\h*$)' ip.txt 
7
43
  • -oP imprime apenas a parte correspondente, usa o PCRE
  • ^\h*\K ignora o início dos caracteres em branco da linha
  • \d+ do número a ser impresso
  • (?=\h+60\h*$) apenas se for seguido por caracteres em branco, então 60 e depois espaços em branco opcionais até o final da linha

Ou use apenas awk para processamento baseado em campo;)

    
por 26.07.2018 / 14:38
4

Retirando apenas o primeiro campo das linhas onde o segundo campo é exatamente 60 (deve funcionar com qualquer awk, não apenas com o GNU awk):

awk '$2 == "60" {print $1}' < file 

Ou com grep e sed :

grep -E '^[[:space:]]*[[:digit:]]+[[:space:]]+60[[:space:]]*$' < file |
   sed -e 's/^[[:space:]]*//' -e 's/[[:space:]].*//'

Um one-liner feio no awk para o caso geral em que você quer linhas com 60 , mas exclui exatamente as que também têm o par 72,96 :

awk 'function f(n) { return ($2 ~ "(^|,)" n "(,|$)") }
     f(60) && ! (f(72) && f(96)) {print NR, $1}' < file 

A função f(n) verifica se n está dentro da lista de números no segundo campo (assumindo que os números são separados por vírgulas ou início / fim de campo). Então, apenas verificamos que 60 está presente e o par 72,96 não está. A saída é o número da linha ( NR ) e o primeiro campo, mas é fácil remover o número da linha se você não quiser.

    
por 26.07.2018 / 14:31
1

Tente:

$ cat infile
63 41,3,11,12 
  1 31,60,72,96 
  7 41,3,31,14,15,68,59,60 
  7 60,72,96 
  7 60 
  1 41,3,31,31,14,15,68,59,60 
  60 41,3,115,12,13,66,96 
  1 41,3,11,12,13,66,96   7 60,72,96 
  7 60 
3 601
 2 60,72,962
5 60,3
43 60   
3 52360

$ grep -oP '^\s*[0-9]+(?= 60\s*$)' infile
  7
  7
43   

Descrição:

grep -P '^             # grep from start of line
\s*                    # followed by optional spaces
[0-9]+                 # followed by some decimal digits
(?= 60\s*$)            # That have a <space>60<space(s)><end of line>
                       # but do not capture the 60.
' infile
    
por 26.07.2018 / 16:15
0

Podemos usar awk para dividir o segundo campo delimitado por espaços em branco em vírgulas. Se o resultado do campo dividido for mais de um valor único, não é interessante, caso contrário, se ele for 60, imprima o primeiro campo delimitado por espaço em branco:

awk 'split($2, a, ",") == 1 && $2 == 60 { print $1 }' <file

Para os dados de exemplo fornecidos, isso imprime 7 .

    
por 26.07.2018 / 16:07