Dlaczego gwiazdka [az] odpowiada numerom?


13

Mam 3 katalogi na bieżącej ścieżce.

$ls
a_0db_data  a_clean_0db_data  a_clean_data
$ls a_*_data
a_0db_data:

a_clean_0db_data:

a_clean_data:

$ls a_[a-z]*_data
a_clean_0db_data:

a_clean_data:

Spodziewałem się, że ostatnie polecenie ls będzie pasować tylko a_clean_data. Dlaczego pasuje również do tego, który zawiera 0?

bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)

2
Zobacz to pytanie, aby uzyskać więcej informacji na temat różnicy między wyrażeniem regularnym a globem.
terdon

4
Więc fakt, że a_*_datapasował do któregoś z tych plików, nie zaskoczył cię?
Cthulhu,

@Cthulhu masz mnie!
user13107,

Odpowiedzi:


29

Ta [a-z]część nie pasuje do liczby; to jest *. Być może mylisz globbing powłoki i wyrażenia regularne .

Narzędzia lubią grepprzyjmować różne smaki regexes ( podstawowe domyślnie -Edla przedłużony -Pdo Perl regex )

Np. ( -vOdwraca dopasowanie)

$ ls a_[a-z]*_data | grep -v "[0-9]"
a_clean_data

Jeśli chcesz użyć wyrażenia regularnego, oto przykład, jak sprawdzić, czy zmienna $refjest liczbą całkowitą:

re='^[0-9]+$'
if ! [[ $ref =~ $re ]] ; then
  echo "error"
fi

Jak zatem użyć wyrażenia regularnego bash? (patrz tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html )
13107


21

Problem w tym: dlaczego a_[a-z]*_datapasuje a_clean_0db_data?

Można to podzielić na cztery części:

  • a_dopasowuje początek a_clean_0db_data, pozostawiając clean_0db_datado dopasowania

  • [a-z]dopasowuje dowolny znak z zakresu a-z(np. c), pozostawiając lean_0db_datado dopasowania

  • * dopasowuje dowolną liczbę znaków, np lean_0db

  • _data pasuje do końcowego _data

W wyrażeniach regularnych [a-z]*oznaczałoby to dowolną liczbę znaków (w tym zero) z zakresu a..z , ale masz do czynienia z globowaniem powłoki, a nie z wyrażeniami regularnymi.

Jeśli potrzebujesz wyrażeń regularnych, kilka findimplementacji ma -regexpredykat:

find . -maxdepth 1 -regex "^.*/a_[a-z]*_data$"

-maxdepthJest tylko tutaj, aby ograniczyć wyniki wyszukiwania dla różnych wyszukiwarek do folderu w którym jesteś. Na wyrażenie regularne pasuje do całego pliku, więc dodałem ^.*/dopasować path-części


11

*we wzorach powłok dopasowuje 0 lub więcej znaków. Nie należy go mylić z *operatorem wyrażenia regularnego, który oznacza 0 lub więcej poprzedniego atomu .

W *podstawowych wzorcach powłok nie ma odpowiednika wyrażenia regularnego . Jednak różne powłoki mają do tego rozszerzenia.

  • kshma *(something):

    ls a_*([a-z])_data
  • możesz mieć to samo bashz shopt -s extgloblub zshz setopt kshglob:

    shopt -s extglob
    ls a_*([a-z])_data
  • In zshz extendedglobwłączonym #jest równoważne wyrażeniu regularnemu *:

    setopt extendedglob
    ls a_[a-z]#_data
  • W najnowszych wersjach ksh93możesz także używać wyrażeń regularnych w globach. Tutaj z rozszerzonymi wyrażeniami regularnymi:

    ls ~(E:a_[a-z]*_data)

Pamiętaj, że [a-z]pasuje do różnych rzeczy w zależności od bieżących ustawień regionalnych. Zazwyczaj dopasowuje tylko 26 ado złacińskich nieakcentowanych liter w Custawieniach regionalnych. W innych lokalizacjach zazwyczaj pasuje więcej i nie zawsze ma to sens. Aby dopasować literę w swoim regionie, możesz preferować [[:alpha:]].


Czy możesz podać przykład [a-z]dopasowania więcej niż 26 liter pasujących do ustawień regionalnych C? Pamiętam, kiedy po raz ostatni na to patrzyłem, wszystkie kodowania praktycznie stosowane w wariantach Uniksa miały ISO-646 jako podstawę (wtedy górne 128 kodów było używane inaczej, bezpośrednio dla znaków w kodowaniach takich jak ISO-8859-X, połączone w kodowania takie jak UTF-8 lub rodzina EUC). Nawet AIX nie miał ustawień narodowych EBCDIC (przynajmniej dla mnie dostępnych). Pamiętam, jak próbowałem sprawdzić, czy standardy POSIX / UNIX tego wymagały, ale nie pamiętam wyniku.
AProgrammer

1
@AProgrammer, niezależny od kodowania, oparty na kolejności sortowania (LC_COLLATE). [a-z]ogólnie zawiera élub í(ale niekoniecznie ź) w lokalizacjach, w których zestaw znaków ma je, niezależnie od tego, czy kod w tym kodowaniu jest między kodem ai z, czy nie. Tylko ustawienia regionalne C gwarantują porządek sortowania na podstawie wartości punktu kodowego. Zobacz tę inną odpowiedź, aby uzyskać więcej informacji.
Stéphane Chazelas,

Ok, brakowało mi to, że zakres został zinterpretowany zgodnie z bieżącą sekwencją zestawiania.
AProgrammer
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.