Zacznę od stwierdzenia, że uważam, że ten problem jest nieco mniej niewinny niż się wydaje.
Co muszę zrobić: sprawdź folder w zmiennej środowiskowej PATH. Może być na początku lub gdzieś później. Muszę tylko sprawdzić, czy ten folder tam jest.
Przykład mojego problemu - użyjmy /opt/gnome
.
SCENARIUSZ 1: folder nie znajduje się na początku ŚCIEŻKI
# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
Zauważ, że grep musi być wystarczająco specyficzny, aby się nie wyłapał /var/opt/gnome
. Stąd dwukropek.
SCENARIUSZ 2: folder znajduje się na początku ŚCIEŻKI.
# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
To jest mój problem - muszę szukać dwukropka lub początku linii w tym folderze. Chciałbym zrobić jedno z tych dwóch wyrażeń w nawiasach:
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
ALE [^
i [:
mają swoje własne znaczenie. Dlatego dwa powyższe polecenia nie działają.
Czy istnieje sposób na grep dla tych dwóch scenariuszy za pomocą jednego polecenia?
źródło
/opt/gnome:
lub/opt/gnome$
, znajdziesz/opt/gnome-foo
lub/opt/gnome/bar
.grep '^\(any number of other matches:*:\)*my match\(:.*\)*$'
Odpowiedzi:
Jeśli sprawdzasz zawartość
PATH
zmiennej środowiskowej, zamiast szukać czegoś w pliku,grep
oznacza to, że jest to niewłaściwe narzędzie. Łatwiej (i szybciej i prawdopodobnie bardziej czytelnie) jest to zrobić w powłoce.W bash, ksh i zsh:
Przenośny:
Zwróć uwagę na użycie
:$PATH:
zamiast$PATH
; w ten sposób komponent jest zawsze otoczony dwukropkami w ciągu wyszukiwania, nawet jeśli był na początku lub na końcu$PATH
.Jeśli przeszukujesz wiersz pliku, możesz użyć rozszerzonego wyrażenia regularnego (tj. Wymagającego
grep -E
),(^|:)/opt/gnome($|:)
aby dopasować,/opt/gnome
ale tylko wtedy, gdy jest on na początku linii lub po dwukropku i tylko jeśli jest na końcu linia lub dwukropek.źródło
Możesz użyć rozszerzonych wyrażeń regularnych, używając tylko
grep -E
Jeśli chcesz uniknąć fałszywych trafień, musisz dopasować początek i koniec ścieżki, którą próbujesz znaleźć.
Na początku odpowiada instancji:
Dopasowuje również instancję na środku:
Unikanie fałszywych trafień:
Brak meczów.
Kompaktowy i elegancki. Testowane na Debianie 7.
źródło
egrep
jest przestarzała wykorzystaniegrep -E
(źródło:man grep
)-w
opcja ma pewne problemy. Tylko cyfry, litery i podkreślenie są uważane za „słowa”. Więc niektóre niezwykłe, ale możliwe znaki spowodują, że się nie powiedzie. Przykładecho '/sbin:/usr/sbin:/var-/opt/gnome' | grep -w "/opt/gnome"
iecho '/sbin:/usr/sbin:/var./opt/gnome' | grep -w "/opt/gnome"
. Te dają złe wyniki./opt/gnome/somethingelse
.echo "/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta" | grep -E "(:|^)/opt/gnome(:|$)"
. Edycja odpowiedzi.Jeśli nie jesteś ślubem
grep
, możesz użyćawk
i oddzielić rekordy:
źródło
Możesz także użyć
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
który dzieli zmienną ścieżki na osobne linie (po jednej na ścieżkę), dzięki czemu
grep -x
można szukać dokładnych wyników. Ma to oczywiście tę wadę, że wymaga dodatkowego procesutr
. I to nie będzie działać, gdy nazwa folderu wPATH
zawiera znaki nowego wiersza.źródło
Nie wiem, czy to wystarczy na odpowiedź, ale
zaspokoi twoją potrzebę.
ale
źródło
/
nie jest częścią słowa, aler
jest./opt/gnome-beta
,/home/bob/opt/gnome
...grep -w /usr/local -o <<< /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
------/usr/local /usr/local /usr/local
Aby wybrać
/opt/gnome
otoczony znaków spoza słowa (nowe linie:
,/
itp), spróbuj tego:źródło
Możesz to zrobić niezawodnie i przy niewielkim wysiłku
grep
. Możesz skorzystać z rozszerzeń, które są szeroko dostępne, spośród których wiele rozwiązań zostało już zaoferowanych, ale nawet w przypadku zwykłego wyrażenia regularnego można to łatwo zrobić, chociaż na pierwszy rzut oka może to nie być intuicyjne.Z podstawowym wyrażeniem regularnym - i tak też jest
grep
- zawsze masz dwie niezawodne kotwice - głowę i ogon linii. Możesz zakotwiczyć dopasowanie do obu tych elementów, niezależnie od ich położenia na linii, np .:grep
dopasuje od początku wiersza tyle wystąpień\(grouped\)
podwyrażeń, ile musi napotkać następny separator, a następnie wyraźne dopasowanie, i od końca dopasowania do końca linii w ten sam sposób. Jeśli twoje jawne dopasowanie nie zostanie wyraźnie dopasowane , nie powiedzie się i nic nie wydrukuje.A więc możesz zrobić na przykład:
Sam zobacz:
WYNIK
źródło
zauważyłeś przypadek na krawędzi ... można go uniknąć, wymuszając pojawienie się: na początku wiersza:
lub jeśli ścieżka jest dokładna, dodaj również jeden na końcu, aby upewnić się, że jest ograniczona:
źródło