Încerc să scriu un script bash care conține o funcție astfel încât atunci când se administrează un .tar
, .tar.bz2
, .tar.gz
etc. fișierul se folosește tar cu switch-uri relevante pentru a decomprima fișierul.
Eu sunt, folosind elif apoi declarații care testa nume de fișier pentru a vedea ce se termină cu și nu pot ajunge la meci, cu regex metacharacters.
Pentru a salva în mod constant rescrie scenariul, eu sunt, folosind 'de testare' de la linia de comandă, am crezut că declarația de mai jos ar trebui să funcționeze, am incercat toate combinatiile de paranteze, ghilimele și metacharaters posibil și încă nu reușește.
test sed-4.2.2.tar.bz2 = tar\.bz2$; echo $?
(this returns 1, false)
Am'm sigur că problema este una simplă și am'am cautat peste tot, dar nu pot înțelege cum să o facă. Stie cineva cum pot face asta?
Pentru a se potrivi regexes aveți nevoie pentru a utiliza =~
operator.
Încercați acest lucru:
[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched
Alternativ, puteți utiliza metacaractere (în loc de regexes) cu ==
operator:
[[ sed-4.2.2.tar.bz2 == *tar.bz2 ]] && echo matched
Dacă portabilitatea nu este un motiv de îngrijorare, se recomanda folosirea [["în loc de" ["sau" test
ca este mai sigur și mult mai puternic. A se vedea [care este diferența între test, [ i [[ ?]1 pentru detalii.
extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xvjf $1 ;;
*.tar.gz) tar xvzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) rar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xvf $1 ;;
*.tbz2) tar xvjf $1 ;;
*.tgz) tar xvzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "don't know '$1'..." ;;
esac
else
echo "'$1' is not a valid file!"
fi
}
Ca răspuns la Varsator Putere în comentariul de mai sus, Avem nevoie pentru a stoca regex pe un var`
Variabila BASH_REMATCH este stabilit după meci expresia, și ${BASH_REMATCH[n]} se va potrivi cel mai inalt grup înfășurat în paranteze ie în următoarele ${BASH_REMATCH[1]} = "comprimat" " și " ${BASH_REMATCH[2]} = ".gz"
if [[ "compressed.gz" =~ ^(.*)(\.[a-z]{1,5})$ ]];
then
echo ${BASH_REMATCH[2]} ;
else
echo "Not proper format";
fi
(Regex de mai sus este't menit să fie unul valid de fișier denumirea și extensii, dar funcționează pentru exemplu)
Eu nu't au suficient rep sa comenteze aici, așa că m-am'm a depune un nou răspuns pentru a îmbunătăți pe dogbane's a răspunde. Dot . în regexp
`[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo comparat
de fapt va potrivi cu orice caracter, nu numai literal dot între 'tar.bz2', de exemplu
[[ sed-4.2.2.tar4bz2 =~ tar.bz2$ ]] && echo matched
[[ sed-4.2.2.tar§bz2 =~ tar.bz2$ ]] && echo matched
sau ceva care nu't nevoie de a scăpa cu '\'. Strict sintaxa ar trebui să fie apoi
[[ sed-4.2.2.tar.bz2 =~ tar\.bz2$ ]] && echo matched
sau puteți merge chiar mai stricte și, de asemenea, include anterioare punct în regex:
[[ sed-4.2.2.tar.bz2 =~ \.tar\.bz2$ ]] && echo matched
Din moment ce sunt utilizați bash, nu't nevoie pentru a crea un proces copil pentru a face acest lucru. Aici este o soluție care îndeplinește în întregime în bash:
[[ $TEST =~ ^(.*):\ +(.*)$ ]] && TEST=${BASH_REMATCH[1]}:${BASH_REMATCH[2]}
Explicație: grupuri înainte și după secvența "de colon și unul sau mai multe spații" sunt stocate de potrivire de model operator în BASH_REMATCH matrice.