Linhas grep começando com 1, mas não com 10, 11, 100, etc [duplicado]

10

Eu tenho um arquivo de dados genômicos com contagens de tags, quero saber quantos são representados uma vez:

$ grep "^1" file |wc -l

inclui todas as linhas que começam com 1, por isso inclui tags representadas 10 vezes, 11, vezes, 100 vezes, 1245 vezes, etc. Como faço isso?

Current format
79      TGCAG.....
1       TGCAG.....
1257    TGCAG.....
1       TGCAG......

Eu só quero as linhas que são:

1       TGCAG.....

Portanto, não é possível incluir as linhas que começam com 1257. OBSERVAÇÃO: O arquivo acima é delimitado por tabulações.

    
por mah 27.07.2018 / 23:51

7 respostas

16

com awk :

awk '$1 == "1" { print; x++ } END { print x, "total matches" }' inputfile
    
por 28.07.2018 / 00:00
27

A questão no corpo

Selecione linhas que começam com 1 e são seguidas por um espaço

grep -c '^1\s'          file
grep -c '^1[[:space:]]' file

Isso também dará a contagem de linhas (sem precisar da chamada para wc)

A questão no título

Um 1 não seguido por outro número (ou nada):

grep -cE '^1([^0-9]|$)' file 

Mas ambas as soluções acima apresentam alguns problemas interessantes, continue lendo.

No corpo da pergunta, o usuário afirma que o arquivo é "delimitado por tabulações".

Delimitador

guia

Uma linha começando com 1 seguido por uma tabulação (uma tabulação real no comando). Isso falhará se o delimitador for um espaço (ou qualquer outro ou nenhum):

grep '^1    ' file

espaço

Uma linha começando com 1 seguido por um espaço (um espaço real no comando). Isso falhará se o delimitador for outro ou nenhum.:

grep '^1 ' file

separador ou espaço

grep '^1(   | )' file
grep '^1[[:blank:]]' file

espaço em branco

Uma opção mais flexível é incluir vários caracteres de espaço (horizontal e vertical). O conjunto de classes de caracteres [:space:] é composto por (espaço), \t (guia horizontal), \r (retorno de carro), \n (nova linha), \v (guia vertical) e \f (feed de formulário). Mas o grep não pode corresponder a uma nova linha (é uma limitação interna que só poderia ser evitada com a opção -z ). É possível usá-lo como uma descrição no delimitador. Também é possível, e mais curto, usar o atalho disponível do GNU de \s :

grep -c '^1[[:space:]]' file
grep -c '^1\s'          file

Mas esta opção falhará se o delimitador for algo como dois pontos : ou qualquer outro caractere de pontuação (ou qualquer letra).

Limite

Ou, podemos usar a transição de um dígito para um limite "não um dígito", bem, na verdade, "um caractere não está em [_[:alnum:]] ( _a-zA-Z0-9 )":

grep -c  '^1\b' file       # portable but not POSIX.
grep -c  '^1\>' file       # portable but not POSIX.
grep -wc '^1'   file       # portable but not POSIX.
grep -c  '^1\W' file       # portable but not POSIX (not match only a '1') (not underscore in BSD).

Isso aceita linhas válidas que começam com 1 e são seguidas por algum caractere de pontuação.

    
por 27.07.2018 / 23:58
18

Parece que você quer isso:

$ grep '^1\b' a
1        TGCAG.....
1        TGCAG......

Para a parte da contagem:

$ grep -c '^1\b' file
2
    
por 28.07.2018 / 00:01
14

Qualquer um deles selecionará linhas com 1 na primeira coluna

awk '$1 == 1'
grep -w '^1'

Estes podem ser estendidos para que você nem precise do wc para contar as linhas

awk '$1==1 { x++ } END { print x }'
grep -cw '^1'
    
por 28.07.2018 / 00:00
5

Usando grep :

grep -c '^1\s' file

Isso corresponderá a qualquer linha que comece com 1 imediatamente seguida por espaço em branco e forneça uma contagem dessas linhas (eliminando a necessidade de wc -l )

$ cat input
79       TGCAG.....
1        TGCAG.....
1257     TGCAG.....
1        TGCAG......
$ grep -Ec '^1\s' input
2
    
por 27.07.2018 / 23:54
3

Boas respostas aqui, mas assumindo que nem todas as linhas terminam em um espaço (como se você tivesse algumas que realmente chegam ao seu "="), você pode usar isto:

 grep -c "^1[^0-9]" file

Basicamente, corresponde a qualquer linha que comece com uma, seguida por um não dígito, incluindo o espaço em branco. Um pouco mais detalhado, mas também mais infalível. (Embora seja importante notar que não há nada aqui para a condição nula de apenas um-em-linha, não é sensível ao fim de linha.)

    
por 28.07.2018 / 10:58
0

Você também pode usar a linha abaixo:

$ awk -F' ' '{if($1=="1") print $0}' <your file name> | wc -l

O parâmetro -F torna o separador de campos um espaço em branco. Se o valor do primeiro campo for '1', sua linha será impressa.

    
por 28.07.2018 / 12:59