Contar o número de linhas com um determinado valor em uma coluna para todos os arquivos no diretório recursivamente

3

Eu tenho 40 arquivos em um diretório e quero contar o número de vezes que há uma linha com um "2" na primeira coluna de cada arquivo individualmente.

Estou tentando algo assim, mas imprime a soma total de cada arquivo e quero as somas individuais:

find . -type f -print0 | xargs -0 awk '($1=="2"){++count} END {print count}'

Só para deixar claro, este é um exemplo:

FILE_1

2   345     123     4
2   4567    2344    6
3   2345    657     87
6   234     345     6

FILE_2

1   12  436 7
2   54  86  8
2   23  48  0
2   098 0   8
8   98  9   0

IMPRIMIR:

FILE_1 2
FILE_2 3

O que estou realmente conseguindo:

IMPRIMIR:

5 

Obrigado pela sua ajuda!

    
por Rebe 10.07.2013 / 21:51

3 respostas

4

Você pode ter grep contando-as para você. Supondo que as linhas que você precisa começam com 2 , você pode usar o seguinte:

grep -c '^[[:space:]]*2\>' $(find . -type f -print0 | xargs -0 echo)

O \> no final da regex garante que a correspondência seja interrompida em um "limite de palavras" para evitar falsos alarmes, como linhas iniciadas por 20 em vez de 2.

Nota:

Se os "40 arquivos" que você está procurando estiverem no mesmo diretório (não em subdiretórios), você pode fazer com que find pesquise apenas no diretório atual sem recursionar (para obter menos latência), como então:

find -maxdepth 1 . -type f -print0

Atualização:

Para corresponder arquivos onde o 2 ocorre em uma coluna diferente da primeira, você pode fazer isso:

COLNUM=3
TOMATCH=$(($COLNUM-1))
grep -cE "^[[:space:]]*([0-9]+[[:space:]]+){$TOMATCH}2\>" \
$(find . -type f -print0 | xargs -0 echo)

Você pode alterar COLNUM , conforme necessário. Basicamente, o que isto significa é que ele tenta igualar as colunas COLNUM-1 seguido por um 2 em um limite de palavra. A opção -E é necessária para ativar expressões regulares estendidas, o que permite usar a notação {} para especificar um quantificador numérico (ou seja, 'corresponde ao padrão anterior muitas vezes').

No entanto, observe que, se você inserir um número de coluna que não existe no arquivo, o regex falhará silenciosamente.

    
por 10.07.2013 / 22:00
2

Algumas soluções:

  1. execute awk em cada arquivo usando find -exec option:

    find . -type f \
    -exec awk '($1=="2"){++count}END{print FILENAME ": " count}' {} \;
    
  2. use a variável awk FNR para detectar a alteração do arquivo no script do awk:

    find . -type f -print0 | xargs -0 \
    awk 'FNR==1{if (NR!=1){print count} printf("%s: ", FILENAME);}($1=="2"){++count}END{print count}'
    
por 10.07.2013 / 22:14
0

Se você não se importa em alterar a saída, pode fazer o seguinte:

$ grep "^2" *|awk '{print $1}'|uniq -c
      2 FILE_1:2
      3 FILE_2:2

Se você quiser sua saída PRINT:

$ grep "^2" *|awk '{print $1}'|uniq -c|sed 's/:2//'|awk '{print $2, $1}'
FILE_1 2
FILE_2 3
    
por 10.07.2013 / 22:19