Correspondência de regex no CLI

3

Existe algo como uma lógica para o cli? Eu quero conseguir isso

mv -t newfolder *.(png|jpg)

para que todos os arquivos jpg e png sejam movidos para a nova pasta. Eu sei que isso poderia ser feito com

mv -t newfolder *.png && mv -t newfolder *.jpg

Mas há algum açúcar sytactic, não é?

    
por ManuelSchneid3r 07.02.2013 / 15:54

5 respostas

4

No Bash:

mv -t newfolder *.@(png|jpg)
  • ? (padrão) Corresponde a zero ou uma ocorrência dos padrões fornecidos
  • * (padrão) Corresponde a zero ou mais ocorrências dos padrões fornecidos
  • + (padrão) Corresponde a uma ou mais ocorrências dos padrões fornecidos
  • @ (padrão) Corresponde a um dos padrões fornecidos
  • ! (padrão) Corresponde a qualquer coisa, exceto um dos padrões fornecidos

Requer a opção extglob:

$ shopt extglob
extglob         on

Se estiver desligado, você pode ligá-lo com

$ shopt -s extglob
    
por 07.02.2013 / 16:05
2
mv -t newfolder *.(png|jpg)

É a sintaxe zsh , mas você precisa ativá-la com:

setopt extended_glob

A rigor, você deve escrever:

mv -t newfolder -- *.(png|jpg)

Caso contrário, se alguns nomes de arquivo começarem com um caractere - , ele não funcionará corretamente.

mv -t newfolder -- *.@(png|jpg)

é a sintaxe ksh . Ele pode ser reconhecido por zsh se você ativar a opção kshglob ( setopt kshglob ) e por bash se você ativar a opção extglob ( shopt -s extglob ).

No entanto, observe que ksh e bash sofrem de um problema nessa instância: se não houver nenhum arquivo png nem jpg , *.@(png|jpg) será passado intocado para mv e, se houver existe um arquivo por esse nome (reconhecidamente incomum), ele será movido para newfolder .

Em bash , você pode evitar esse problema ativando a opção failglob . Em ksh (versões recentes do ksh93 apenas), o melhor que você pode fazer é escrever ~(N)*.@(png|jpg) (que seria equivalente a nullglob no bash ou o (N) globbing qualifier em zsh), o que causaria o padrão para expandir para nada se não houver nenhum arquivo correspondente e, em seguida, você obterá um erro de mv .

    
por 07.02.2013 / 20:55
1

A resposta de Nykakin explica muito. Apenas para adicionar algo apontar -

Não há nada como regex em CLI . É sempre globbing que você vê e usa.

Se isso fosse regex puro, por que não o arquivo e diretórios que começam com um ponto [ . ] são exibidos quando você digita ls * ? Em regex * corresponde a tudo certo? Mas esse não é o caso da glob.

    
por 07.02.2013 / 16:57
1

Como outros já afirmaram, regex não é necessário para atingir seu objetivo. Vou oferecer um exemplo de como realizar isso via regex se a situação exigir isso. O seguinte irá funcionar no bash:

files=();
for file in *; 
    [[ $file =~ \.(png|jpg)$ ]] && files+=("$file")
done

mv -t newfolder "${files[@]}"
    
por 07.02.2013 / 18:10
0

Eu não sei de nada com regexs, ou qualquer açúcar sintático bacana para obter o resultado desejado. Aqui está uma maneira de obter o resultado desejado, no entanto, que usa find.

find . -maxdepth 1 -mindepth 1 -type f -name '*.png' -o -name '*.jpg' -exec mv -t newfolder {} +
    
por 07.02.2013 / 18:16