Regex em find - OS X

1

Não consigo descobrir o que há de errado com meu regex, parece estar funcionando com grep , mas agora com find . Estou tentando encontrar todos os arquivos que seguem a expressão comum em programas de TV, por exemplo. S02E21 .

find -E . -name '.*[sS]{1}[0-9]{1,2}[\.]?[eE]{1}[0-9]{1,2}.*\.mkv'

Não obtenho resultados com find , no entanto, se eu usar a mesma regex em combinação com ls|grep -E '....' , os arquivos serão encontrados conforme o esperado.

    
por user14492 03.05.2016 / 19:13

2 respostas

2

-name aceita padrões de curingas , não regexps e corresponde ao nome do arquivo , não o caminho completo. Use -regex (ou -iregex ) para correspondência de regexp, mas cuidado com o caminho completo. Aqui você poderia fazer:

LC_ALL=C find -E . -iregex '.*s[0-9]{1,2}\.?e[0-9]{1,2}[^/]*\.mkv'

Aqui, estamos substituindo o segundo .* por [^/]* , ou seja, uma sequência de não caracteres / para garantir que o padrão seja igual ao nome do arquivo e não a qualquer um dos componentes do diretório.

Ao corrigir o código de idioma para C com LC_ALL=C , garantimos que . corresponda a qualquer byte e [^/] de qualquer byte, exceto o de byte / caso contrário, você poderia encontrar problemas com nomes de arquivos ou diretórios codificados em um conjunto de caracteres diferente do da sua localidade. A correção da localidade para C também garante que e corresponda apenas a e e E (e s on s e S ) com -iregex .

Observe que [\.] corresponde a uma barra invertida ou a um ponto. Para corresponder a um ponto, é \. ou [.] . Também x{1} é o mesmo que x , então eu removi esses {1} para simplificação.

Verifique a sua página de manual para obter detalhes. Observe que nenhum dos -E , -regex ou -iregex são padrão .

Pode ser simplificado para

LC_ALL=C find -E . -iregex '.*s[0-9]{1,2}\.?e[0-9][^/]*\.mkv'

Como o segundo dígito, se houver, também será correspondido por [^/] .

O equivalente padrão usando padrões de curinga seria semelhante a:

LC_ALL=C find . -name '*[sS][0-9][0-9].[eE][0-9]*.mkv' \
             -o -name '*[sS][0-9].[eE][0-9]*.mkv' \
             -o -name '*[sS][0-9][0-9][eE][0-9]*.mkv' \
             -o -name '*[sS][0-9][eE][0-9]*.mkv'
Os

padrões de caracteres curinga, ao contrário das expressões regulares estendidas, não possuem um operador de alternância nem o equivalente a ? ou {n,p} , portanto, precisamos de quatro padrões para abranger todas as possibilidades.

Você também pode usar um shell com globalização recursiva e padrões avançados de caracteres curinga, como zsh :

setopt extendedglob
ls -lrtd -- **/(#i)*s<->e<->*.mkv
  • % recursiva de**/
  • (#i) correspondência insensível a maiúsculas
  • <-> qualquer número decimal

Passando para ls -lrtd aqui para imprimir uma lista com detalhes, classificados pela hora da última modificação, embora, é claro, você possa usar qualquer comando.

    
por 03.05.2016 / 19:19
0

find dir -name apenas suporta caracteres glob do nome do arquivo shell conforme documentado por man fnmatch .

Algumas implementações de localização suportam extensões não padrão para expressões regulares. Verifique sua página find man.

    
por 03.05.2016 / 19:19