Procurando por ocorrências de, antes de uma palavra específica

1

Eu tenho um arquivo csv no qual eu tenho que encontrar o número de linhas com a palavra específica "Feliz" na 6ª posição, ie. depois de 5 vírgulas.

Então estou escrevendo isso:

grep -P -c  ",\{5,\}"'Happy' file.csv

mas está retornando 0.

O conteúdo do arquivo é:

123,abc,def,ghi,e444,Happy,224,e44

    
por Aquarius24 17.10.2015 / 10:10

3 respostas

3
grep -E '^([^,]*,){5}Happy' <in >out

Isso só encontrará Happy se for imediatamente adjacente à 5ª vírgula. Se você quiser encontrá-lo em qualquer lugar dentro do sexto campo, adicione um pouco de espaço para respirar:

grep -E '^([^,]*,){5}[^,]*Happy' <in >out

Se você quiser apenas uma contagem das linhas correspondentes, use a opção -c :

grep -cE '^([^,]*,){5}[^,]*Happy' <in >out

Estou muito familiarizado com expressões regulares, mas mesmo se não estivesse, acho que ainda escolheria re sintaxe em relação a outros tipos. Depois de pegar o jeito de algumas linhas de base, o resto cai junto. Expressões regulares descrevem a entrada combinando muito poucos blocos básicos de construção de várias maneiras.

  • * Kleene Star

    • indica que a expressão imediatamente anterior ocorre 0 ou mais vezes
  • [ expressão de colchete ]

    • indica uma ocorrência de qualquer um (possivelmente ^ negado) conjunto de caracteres contidos
  • { min , max } repetição

    • especifica uma contagem de ocorrências para a expressão imediatamente anterior

    • o metexaractere regexp ? estendido é apenas uma abreviação de {0,1} .

  • ( expressão sub )

    • reúne qualquer expressão contida em uma única expressão.
  • . character

    • corresponde a qualquer caractere único
  • ^|$

    • indicam uma âncora de cabeça de linha ^ para a expressão a seguir ou uma alternância | entre expressões ou uma âncora de linha de frente $

Esses são os princípios básicos. A sintaxe de expressão regular POSIX -E xtended também inclui o Kleene + - que é idêntico ao * em todos os sentidos, exceto que requer pelo menos uma correspondência para a expressão anterior. Há também todos os tipos de sutilezas possíveis para fazer com [ expressões de colchetes ] - especialmente para fazer com as classes de caracteres [(:|.|=) internas (=|.|:)] e como elas correspondem às repetições. E a maioria das implementações, na verdade, estende a re-sintaxe estendida, pelo menos, para lidar com as referências anteriores de% coexde% regexp% para uma expressão de \[num] anterior ( .

Mas, considerando apenas o básico, qualquer uma das expressões acima ou qualquer outro caractere único é uma expressão em si, e todas elas se combinam na expressão geral para descrever a correspondência que você deseja.

Coloque tudo isso junto e a expressão ) acima será dividida da seguinte maneira:

  • grep

    • Começando na posição mais à esquerda, uma linha combinada não deve conter mais ou menos de 5 sequências de 0 ou mais caracteres não-vírgula, cada uma das quais é seguida imediatamente por um caractere vírgula e tudo é imediatamente seguido pelo caractere string ^([^,]*,){5}Happy .
por 17.10.2015 / 10:24
3

Você pode fazer:

grep '^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,Happy' file.txt

Assumindo 5 vírgulas desde o início da linha, se de qualquer lugar na linha, apenas remova% inicial ^ .

Seu padrão é simplesmente procurar linhas com cinco ou mais vírgulas sucessivamente.

    
por 17.10.2015 / 10:16
2

Acho que usar awk torna o comando mais simples e mais fácil ao lidar com arquivos CSV. Tem suporte natural para o conceito de campos que facilitam muito a vida.

awk -F, '$6 == "Happy" { count++ } END { print count }' file.csv

O comando é dividido da seguinte forma:

awk             -  The command to run
-F,             -  Use a comma as the field separator
$6 == "Happy"   -  Only match lines where the sixth field equals "Happy"
{ count++ }     -  For each line matched, add one to the "count" variable
END             -  When all that is done...
{ print count } -  ...print the value of "count"
file.csv        -  The file to read from
    
por 17.10.2015 / 10:29

Tags