Bash
Mönstermatchning och regelbundna uttryck
Sök…
Syntax
- $ shopt -u-alternativ # Inaktivera Bashs inbyggda 'alternativ'
- $ shopt -s alternativ # Aktivera Bashs inbyggda "alternativ"
Anmärkningar
Karaktär klasser
Giltiga karaktärsklasser för []
glob definieras av POSIX-standarden:
alnum alpha ascii blank cntrl-siffrig graf nedre tryck punkteringsavstånd övre ordet xdigit
Inuti []
mer än en teckenklass eller intervall användas, t.ex.
$ echo a[a-z[:blank:]0-9]*
matchar alla filer som börjar med a
och följs av antingen en liten bokstav eller en tom eller en siffra.
Man bör dock tänka på att en []
jordklot bara kan negeras helt och inte bara delar av den. Den negerande karaktären måste vara det första tecknet efter öppnandet [
t.ex., detta uttryck matchar alla filer som inte börjar med en a
$ echo [^a]*
Följande matchar alla filer som börjar med antingen en siffra eller en ^
$ echo [[:alpha:]^a]*
Det stämmer inte med någon fil eller mapp som börjar med bokstaven förutom en a
eftersom ^
tolkas som en bokstavlig ^
.
Rymmer glob-karaktärer
Det är möjligt att en fil eller mapp innehåller ett globaltecken som en del av dess namn. I det här fallet kan en glob undkomma med föregående \
för en bokstavlig matchning. Ett annat tillvägagångssätt är att använda dubbla ""
eller enstaka ''
citat för att adressera filen. Bash bearbetar inte jordklot som är inneslutna i ""
eller ''
.
Skillnad mellan regelbundna uttryck
Den mest signifikanta skillnaden mellan globs och Regular Expressions är att ett giltigt Regular Expressions kräver både en kval och en kvantifierare. En kvalificerar identifierar vad som ska matchas och en kvantifierare berättar hur ofta man ska matcha kvalet. Motsvarande RegEx till *
glob är .*
Där .
står för valfri karaktär och *
står för noll eller fler matchningar av föregående karaktär. Motsvarande RegEx för ?
glob är .{1}
. Som tidigare, kvalet .
matchar valfritt tecken och {1}
indikerar att matcha föregående kval exakt en gång. Detta bör inte förväxlas med ?
kvantifierare, som matchar noll eller en gång i en RegEx. Globen []
kan användas på samma sätt i en RegEx, så länge den följs av en obligatorisk kvantifierare.
Likvärdiga regelbundna uttryck
glob | RegEx |
---|---|
* | .* |
? | . |
[] | [] |
Kontrollera om en sträng matchar ett vanligt uttryck
Kontrollera om en sträng består av exakt åtta siffror:
$ date=20150624
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
yes
$ date=hello
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
no
* Globen
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Asterisken * är förmodligen den mest använda kloden. Det matchar helt enkelt alla strängar
$ echo *acy
macy stacy tracy
En enda * matchar inte filer och mappar som finns i undermappar
$ echo *
emptyfolder folder macy stacy tracy
$ echo folder/*
folder/anotherfolder folder/subfolder
** Globen
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -s globstar
Bash kan tolka två angränsande asterisker som en enda glob. Med globstar
alternativet aktiverat kan detta användas för att matcha mappar som ligger djupare i katalogstrukturen
echo **
emptyfolder folder folder/anotherfolder folder/anotherfolder/content folder/anotherfolder/content/deepfolder folder/anotherfolder/content/deepfolder/file folder/subfolder folder/subfolder/content folder/subfolder/content/deepfolder folder/subfolder/content/deepfolder/file macy stacy tracy
**
kan tänkas på en vägutvidgning, oavsett hur djup vägen är. Detta exempel matchar alla filer eller mappar som börjar med deep
, oavsett hur djup den är kapslad:
$ echo **/deep*
folder/anotherfolder/content/deepfolder folder/subfolder/content/deepfolder
? glob
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
?
matchar helt enkelt exakt en karaktär
$ echo ?acy
macy
$ echo ??acy
stacy tracy
Globen []
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Om det finns behov av att matcha specifika tecken kan '[]' användas. Alla tecken i '[]' matchas exakt en gång.
$ echo [m]acy
macy
$ echo [st][tr]acy
stacy tracy
Den []
glob är dock mer mångsidig än just det. Det möjliggör också en negativ matchning och till och med matchande intervall av karaktärer och karaktärsklass. En negativ matchning uppnås genom att använda !
eller ^
som det första tecknet som följer [
. Vi kan matcha stacy
by
$ echo [!t][^r]acy
stacy
Här berättar vi om vi vill matcha bara filer som inte börjar med en t
och den andra bokstaven är inte en r
och filen slutar i acy
.
Områden kan matchas genom att separera ett par tecken med bindestreck ( -
). Alla tecken som faller mellan dessa två slutande tecken - inklusive - kommer att matchas. Exempelvis är [rt]
ekvivalent med [rst]
$ echo [r-t][r-t]acy
stacy tracy
Teckenklasser kan matchas av [:class:]
, t.ex. för att matcha filer som innehåller ett blanksteg
$ echo *[[:blank:]]*
file with space
Matchar dolda filer
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Det inbyggda alternativet Bash dotglob gör det möjligt att matcha dolda filer och mappar, dvs filer och mappar som börjar med en .
$ shopt -s dotglob
$ echo *
file with space folder .hiddenfile macy stacy tracy
Fall okänslig matchning
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Att ställa in alternativet nocaseglob
kommer att matcha kloden på ett okänsligt fall
$ echo M*
M*
$ shopt -s nocaseglob
$ echo M*
macy
Beteende när en glob inte matchar någonting
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Om glob inte matchar något bestäms resultatet av alternativen nullglob
och failglob
. Om ingen av dem är inställd kommer Bash att returnera själva klotet om ingenting matchas
$ echo no*match
no*match
Om nullglob
är aktiverat nullglob
ingenting ( null
):
$ shopt -s nullglob
$ echo no*match
$
Om failglob
är aktiverat failglob
ett felmeddelande:
$ shopt -s failglob
$ echo no*match
bash: no match: no*match
$
Observera att alternativet failglob
ersätter nullglob
alternativet, dvs om nullglob
och failglob
båda är inställda, kommer - om det inte finns någon matchning - att ett fel returneras.
Utökad globbning
Förberedelse
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Bashs inbyggda extglob
alternativ kan utöka en global matchningskapacitet
shopt -s extglob
Följande undermönster innefattar giltiga utvidgade jordklot:
-
?(pattern-list)
- Matchar noll eller en förekomst av de givna mönstren -
*(pattern-list)
- Matchar noll eller fler förekomster av de givna mönstren -
+(pattern-list)
- Matchar en eller flera förekomster av de givna mönstren -
@(pattern-list)
- Matchar ett av de givna mönstren -
!(pattern-list)
- Matchar allt utom ett av de givna mönstren
pattern-list
är en lista över jordklot separerade med |
.
$ echo *([r-t])acy
stacy tracy
$ echo *([r-t]|m)acy
macy stacy tracy
$ echo ?([a-z])acy
macy
Själva pattern-list
kan vara en annan, kapslad utökad glob. I exemplet ovan har vi sett att vi kan matcha tracy
och stacy
med *(rt)
. Den här utvidgade klippen kan användas i den negerade utvidgade kloden !(pattern-list)
för att matcha macy
$ echo !(*([r-t]))acy
macy
Det matchar allt som inte börjar med noll eller fler förekomster av bokstäverna r
, s
och t
, som bara lämnar macy
som möjligt matchning.
Regex-matchning
pat='[^0-9]+([0-9]+)'
s='I am a string with some digits 1024'
[[ $s =~ $pat ]] # $pat must be unquoted
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
Produktion:
I am a string with some digits 1024
1024
Istället för att tilldela regex till en variabel ( $pat
) skulle vi också kunna göra:
[[ $s =~ [^0-9]+([0-9]+) ]]
Förklaring
- Konstruktionen
[[ $s =~ $pat ]]
utför regex-matchningen - De fångade grupperna, dvs matchresultaten är tillgängliga i en matris med namnet BASH_REMATCH
- Det 0: e indexet i BASH_REMATCH- matrisen är den totala matchen
- Det i'de indexet i BASH_REMATCH- arrayen är den i'th fångade gruppen, där i = 1, 2, 3 ...
Få fångade grupper från en regex-match mot en sträng
a='I am a simple string with digits 1234'
pat='(.*) ([0-9]+)'
[[ "$a" =~ $pat ]]
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
Produktion:
I am a simple string with digits 1234
I am a simple string with digits
1234