Detectando padrão no final de uma linha com grep

48

Se eu fizer:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

./Cloud:
UFAIZLV2R7.part2.rar.part
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part4.rar.part

Se eu quiser listar apenas os arquivos .rar , e usar grep , ele também mostrará os arquivos .rar.part , o que não é meu desejo.
Estou resolvendo isso usando find ou ls **/*.rar conforme contido em este thread e eles funcionam bem, mas eu gostaria de saber se é possível fazer isso via grep .

Eu tentei (pensando em EOL ):

ls -R | grep ".rar\n"

sem resultados.
Eu acho que o problema está em descobrir se o greping é encontrado no final da linha , mas não tenho certeza.

Qualquer ajuda aqui, por favor?

    
por Sopalajo de Arrierez 13.04.2014 / 01:41

6 respostas

65

A âncora $ corresponde ao final de uma linha.

ls -R | grep '\.rar$'

Você também pode usar find para isso:

find . -name '*.rar'
    
por 13.04.2014 / 01:45
8

Além de sua pergunta, observe que .rar não corresponde apenas a ".rar", mas corresponde a todos os caracteres (incluindo . ) antes do rar . Neste caso, provavelmente não é um problema, mas . deve ser salvo em expressões regulares.

ls -R | grep "\.rar$"
    
por 13.04.2014 / 01:46
5

Você também pode instruir grep a procurar sua sequência começando em um limite de palavra. Um . é um desses limites.

$ ls -R | grep '\brar$'

Exemplo

Digamos que eu tenha esses dados de amostra.

$ ls -1
afile.rar
xrar
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part2.rar.part

Este comando encontrará apenas o arquivo com a extensão .rar .

$ ls -R | grep '\brar$'
afile.rar

Como isso funciona?

The metacharacter \b is an anchor like the caret and the dollar sign. It matches at a position that is called a "word boundary". This match is zero-length.

Situações em que isso não funcionará

Se você tiver arquivos com o nome blah-rar , eles também serão detectados.

$ ls -R | grep '\brar$'
afile-rar
afile.rar

Isso porque outros caracteres, além dos alfanuméricos, são normalmente considerados caracteres de contorno e, portanto, passariam por essa abordagem.

    
por 13.04.2014 / 03:16
0

Basta fazer:

ls -1R -I"?" -I"??" -I"???" -I"*[!.][!r][!a][!r]"

Você não precisa de grep .

NOTA: Os trabalhos acima ... exceto que ele ainda recebe pelo menos afile-rar e eu não entendo o porquê. Vou deixar aqui, mas não tenho orgulho disso. Em qualquer caso, como outros já disseram:

find . '*.rar'
    
por 13.04.2014 / 16:45
0

Use aspas simples para fazer o $ funcionar como final de linha. Se você quiser grep com alguma variável também, use a combinação de aspas duplas e simples como abaixo:

grep "$var"'$'

Minha postagem anterior foi excluída dizendo que é duplicada. Deixe-me explicar como isso é diferente.

As outras postagens mencionam o uso total de aspas duplas "" ou o uso total de aspas simples '' . Ambos têm suas próprias limitações. A seguir explica isso.

O problema com todas as aspas duplas é o seguinte: grep "pattern$" apresenta o seguinte erro: Illegal variable name.

E usar todas as aspas simples funciona, mas se você quiser uma substituição de variável, todas as aspas simples não funcionarão. Por exemplo:

Se eu tiver a string A_BOOK , incluindo outras strings em um arquivo FILE.

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

Se eu definir o BOOK para uma variável BK

set BK = BOOK

Se eu fizer grep com todas as aspas duplas, recebo o seguinte erro: grep "${BK}$" FILE* : 1st $ para substituição de variável, 2nd para final de padrão ( nome da variável ilegal ).

Se eu grep com todas as aspas simples, a substituição da variável não acontece. grep '${BK}$' FILE não retorna nada

Se eu usar uma combinação de aspas duplas e simples, obtenho o que espero. Aspas duplas para substituição de variável e aspas simples para fim de padrão.

$ grep "${BK}"'$'  # << gives expected output
A_BOOK
C_BOOK
    
por 26.06.2018 / 09:46
0

Se depois de seguir o acima e nada funcionar, pode ser devido a terminações de linha. Para corrigir, faça: dos2unix pr0n.txt e faça seu grep novamente.

    
por 15.08.2018 / 01:19

Tags