Estou tentando escrever um script que contém uma função assim quando dado um .tar
, .tar.bz2
, .tar.gz
arquivo etc. ele usa tar com os interruptores relevantes para descompactar o arquivo.
Estou usando as instruções if elif then que testam o nome do arquivo para ver com o que ele termina e não consigo fazer a correspondência usando os metacaracteres regex.
Para economizar constantemente reescrevendo o script que estou usando 'test' na linha de comando, pensei que a instrução abaixo deveria funcionar, tentei todas as combinações de colchetes, aspas e metacaracteres possíveis e, ainda assim, falha.
test sed-4.2.2.tar.bz2 = tar\.bz2$; echo $?
(this returns 1, false)
Tenho certeza de que o problema é simples e procurei em todos os lugares, mas não consigo entender como fazê-lo. Alguém sabe como eu posso fazer isso?
check="^a.*c$";if [[ "abc" =~ $check ]];then echo match;fi
, precisamos armazenar o regex em um var[[ sed-4.2.2.tar.bz2 == "*tar.bz2" ]]
não funcionaria.[[ ! foo =~ bar ]]
.-n 1
parâmetro, nem o coloca automaticamente em uma$REPLY
variável. Cuidado!Uma função para fazer isso
Outra nota
Em resposta ao Aquarius Power no comentário acima,
We need to store the regex on a var
A variável BASH_REMATCH é definida após a correspondência da expressão, e $ {BASH_REMATCH [n]} corresponderá ao enésimo grupo entre parênteses, ou seja, a seguir
${BASH_REMATCH[1]} = "compressed"
e${BASH_REMATCH[2]} = ".gz"
(O regex acima não deve ser válido para nomes e extensões de arquivos, mas funciona como exemplo)
fonte
a
no GNU tar oup
no BSD tar para dizer explicitamente para inferir automaticamente o tipo de compactação da extensão. O GNU tar não fará isso automaticamente caso contrário, e acho que pelo comentário da @GoodPerson que o BSD tar faz isso por padrão.Não tenho representante suficiente para comentar aqui, por isso estou enviando uma nova resposta para melhorar a resposta da dogbane. O ponto . no regexp
[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched
na verdade corresponderá a qualquer caractere, não apenas ao ponto literal entre 'tar.bz2', por exemplo
ou qualquer coisa que não exija escape com '\'. A sintaxe estrita deve então ser
ou você pode ser ainda mais rigoroso e também incluir o ponto anterior na regex:
fonte
Como você está usando o bash, não é necessário criar um processo filho para fazer isso. Aqui está uma solução que a executa inteiramente no bash:
Explicação: Os grupos antes e depois da sequência "dois pontos e um ou mais espaços" são armazenados pelo operador de correspondência de padrões na matriz BASH_REMATCH.
fonte
Funciona para mim!
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
fonte
[[ ... ]]
, o padrão rhs glob não se expande de acordo com o diretório atual, como normalmente faria.[[...]]
, o Bash não realiza a expansão do nome do arquivo. No manual do bash,Word splitting and filename expansion are not performed on the words between the [[ and ]];
shopt -s nocasematch
fonte