Próbuję napisać skrypt bash, który zawiera funkcję, więc kiedy dali .tar
, .tar.bz2
,.tar.gz
itp wykorzystuje plik tar z odpowiednimi przełącznikami do dekompresji pliku.
Używam instrukcji if elif then, które testują nazwę pliku, aby zobaczyć, na czym się kończy, i nie mogę dopasować jej przy użyciu metaznaków wyrażenia regularnego.
Aby zaoszczędzić na ciągłym przepisywaniu skryptu, którego używam „test” w wierszu poleceń, pomyślałem, że poniższe stwierdzenie powinno działać, wypróbowałem każdą możliwą kombinację nawiasów, cudzysłowów i metacharatów i nadal się nie udaje.
test sed-4.2.2.tar.bz2 = tar\.bz2$; echo $?
(this returns 1, false)
Jestem pewien, że problem jest prosty i szukałem wszędzie, ale nie mogę pojąć, jak to zrobić. Czy ktoś wie, jak mogę to zrobić?
check="^a.*c$";if [[ "abc" =~ $check ]];then echo match;fi
, musimy przechowywać wyrażenie regularne w zmiennej[[ sed-4.2.2.tar.bz2 == "*tar.bz2" ]]
nie zadziała.[[ ! foo =~ bar ]]
.-n 1
parametru, ani też nie umieszcza go automatycznie w$REPLY
zmiennej. Uważaj!Funkcja do tego
Inna uwaga
W odpowiedzi na Moc Wodnika w powyższym komentarzu,
We need to store the regex on a var
Zmienna BASH_REMATCH jest ustawiana po dopasowaniu wyrażenia, a $ {BASH_REMATCH [n]} dopasuje n-tą grupę zawiniętą w nawiasy, tj. W następujących
${BASH_REMATCH[1]} = "compressed"
i${BASH_REMATCH[2]} = ".gz"
(Powyższe wyrażenie regularne nie ma być poprawne dla nazewnictwa plików i rozszerzeń, ale działa w tym przykładzie)
źródło
a
na tarach GNU lubp
na tarach BSD, aby jawnie powiedzieć mu, aby automatycznie wywnioskował typ kompresji z rozszerzenia. W przeciwnym razie GNU tar nie zrobi tego automatycznie i zgaduję na podstawie komentarza @GoodPerson, że tar BSD robi to domyślnie.Nie mam wystarczającej liczby przedstawicieli, aby komentować tutaj, więc przesyłam nową odpowiedź, aby poprawić odpowiedź dogbane. Kropka . w wyrażeniu regularnym
[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched
faktycznie dopasuje dowolny znak, nie tylko na przykład dosłowną kropkę między „tar.bz2”
lub cokolwiek, co nie wymaga ucieczki z '\'. W takim przypadku powinna być ścisła składnia
lub możesz pójść jeszcze bardziej restrykcyjnie i uwzględnić również poprzednią kropkę w wyrażeniu regularnym:
źródło
Ponieważ używasz basha, nie musisz w tym celu tworzyć procesu potomnego. Oto jedno rozwiązanie, które wykonuje to całkowicie w bash:
Objaśnienie: Grupy przed i po sekwencji „dwukropek i co najmniej jedna spacja” są zapisywane przez operator dopasowania do wzorca w tablicy BASH_REMATCH.
źródło
Pracuje dla mnie!
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
źródło
[[ ... ]]
wzorzec rhs glob nie rozwija się zgodnie z bieżącym katalogiem, jak to zwykle bywa.[[...]]
Bash nie wykonuje rozszerzania nazw plików. W podręczniku bash,Word splitting and filename expansion are not performed on the words between the [[ and ]];
shopt -s nocasematch
źródło