Use grep para relatar apenas números de linha


106

Tenho um arquivo que possivelmente contém uma formatação incorreta (neste caso, a ocorrência do padrão \\backslash). Eu gostaria de usar greppara retornar apenas os números das linhas onde isso ocorre (como em, a correspondência estava aqui, vá para a linha # x e corrija).

No entanto, não parece haver uma maneira de imprimir o número da linha ( grep -n) e não a correspondência ou a própria linha.

Posso usar outra regex para extrair os números de linha, mas quero ter certeza de que o grep não pode fazer isso sozinho. grep -nochega mais perto, eu acho, mas ainda exibe a correspondência.


1
A resposta mais útil para mim estava na pergunta grep -no:! Isso fez o que eu vim aqui tentar fazer! (ou seja, não imprimir a linha que às vezes é muito longa, por exemplo, arquivos de origem javascript minificados.)
— LondonRob

Respostas:


156

experimentar:

grep -n "text to find" file.ext | cut -f1 -d:

1
Na minha máquina, isso imprime apenas os arquivos correspondentes sem números de linha (então, se eu tiver 3 correspondências dentro de um arquivo, ele será impresso apenas uma vez), o que ainda é muito útil ...
— Mario Awad

3
@MarioAwad, você deve manipular -fparam. Para mim foi -f2. (Sei que isso é coisa velha, mas acho que pode ajudar algumas pobres almas)
— Emil Sierżęga

Obrigado pelo adorável script de shell adhoc do Unix antigo. isso mostra que as ferramentas flexíveis valem sua complexidade e curva de aprendizado!
— Alex

12
grep -n "text to find" file.ext | cut -f1,2 -d:mostra o nome do arquivo e o número da linha.
— Jondlm

2
@jondim só mostra o nome do arquivo se houver mais de um arquivo sendo pesquisado; você precisa adicionar -Hpara forçá-lo a mostrar o nome do arquivo quando houver apenas um arquivo. Por outro lado, você sempre pode usar -hpara dizer a ele para não imprimir o nome do arquivo, não importa quantos arquivos você esteja executando o grep.
— Mark Reed

45

Se você está aberto para usar AWK:

awk '/textstring/ {print FNR}' textfile

Nesse caso, FNR é o número da linha. AWK é uma ótima ferramenta quando você está olhando para grep | cut, ou sempre que você está tentando pegar a saída do grep e manipulá-la.


2
Usa um processo (que importava mais no passado, mas ainda assim) e fácil de entender para iniciantes awk!
— bgStack15

NRfunciona bem quando há apenas um arquivo sendo examinado, como neste caso.
— Mark Reed

Simplesmente brilhante! É tão rápido!
— GTodorov

34

Todas essas respostas requerem que o grep gere todas as linhas correspondentes e, em seguida, canalize-as para outro programa. Se suas linhas forem muito longas, pode ser mais eficiente usar apenas sed para gerar os números das linhas:

sed -n '/pattern/=' filename

2

Versão Bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}

1
E o que acontece se mais de uma linha corresponder a esse padrão?
— Izabera

@izabera add | cauda -1
— Diego

1

Eu recomendo as respostas com sede awkapenas para obter o número da linha, em vez de usar greppara obter a linha correspondente inteira e, em seguida, removê-la da saída com cutou outra ferramenta. Para completar, você também pode usar Perl:

perl -nE '/pattern/ && say $.' filename

ou Ruby:

ruby -ne 'puts $. if /pattern/' filename

0

Você vai querer o segundo campo após os dois pontos, não o primeiro.

grep -n "text to find" file.txt | cut -f2 -d:


Isso funciona se você quiser combinar o texto, mas no caso o número da linha é o que o OP estava pedindo.
— AJP de

0

Para contar o número de linhas que correspondem ao padrão:

grep -n "Pattern" in_file.ext | wc -l 

Para extrair o padrão correspondente

sed -n '/pattern/p' file.est

Para exibir os números de linha em que o padrão foi correspondido

grep -n "pattern" file.ext | cut -f1 -d:

2
O primeiro deve ser apenas "grep -c 'Pattern' in_file.ext". O segundo deve ser "grep -o 'Pattern' in_file.ext". Não há necessidade de envolver sed ou wc.
— thelogix 01 de

0

usando apenas grep :

grep -n "text to find" file.ext | grep -Po '^[^:]+'

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.