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.

Neil
fonte
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:
love_me_some_linux
fonte
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.

brilhante
fonte
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
independente
fonte
2

Versão Bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}
independente
fonte
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
Mark Reed
fonte
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:

Chris
fonte
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:
JstRoRR
fonte
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 '^[^:]+'

Micael Levi
fonte