Dziwne zachowanie „ls -a | grep ^ \. ”


10

Chciałem wyświetlić zawartość pliku pwd i wyświetlić tylko plik zaczynający się od kropki. Próbowałem, ls -a | grep ^\.ale nie mogę zrozumieć, dlaczego dane wyjściowe zawierają również pliki, które nie zaczynają się od kropki. Na przykład:

Pictures
.pip
.pki
.profile
projects
Public

Wiem, że mogę osiągnąć to, co chcę ls -ld .*, jestem ciekawy tego zachowania grepa, którego nie potrafię wyjaśnić.



Dlaczego nie tylko ls -d .*wymienić wszystkie pliki zaczynające się od .?
Barmar,

Uwaga ostrzegawcza: Nigdy nie podłączaj wyjścia ls do innego polecenia. Zamiast tego użyj find. Ls ma zbyt wiele ideosyncrasies, aby można było zaufać. Zobacz: Pitfall 1 na mywiki.wooledge.org/BashPitfalls - to # 1! Reszta strony też jest świetna.
Joe

Odpowiedzi:


20

Przytoczyć argument grep, tym samymls -a | grep '^\.'

Powodem tego jest to, że powłoka obsługuje \.i zamienia ją z powrotem w zwykły ., który grepnastępnie traktuje jako jednoznaczny znak wieloznaczny. W razie wątpliwości zawsze cytuj ciąg znaków, który zawiera (lub może zawierać) znak specjalny dla powłoki.


Dlaczego shell ignoruje \?
ps-aux,

\ jest sekwencją ucieczki, która sprawia, że ​​powłoka traktuje następujący znak jako dosłowny. W tym przypadku grep ^\\.\\ jest traktowane przez powłokę jako pojedynczy odwrotny ukośnik, a ponownie grep traktuje pojedynczy odwrotny ukośnik, a następnie kropkę jako dosłowną kropkę.
Avinash Raj,

11

Musisz umieścić wyrażenie grep w cudzysłowie.

ls -a | grep '^\.'

Uwaga: Nie analizuj danych wyjściowych lspolecenia .


Dlaczego analizowanie wyniku ls jest złe?
ps-aux,

Z linku: W domyślnym trybie, jeśli standardowe wyjście nie jest terminalem, ls oddziela nazwy plików znakami nowej linii. Jest to w porządku, dopóki nie masz pliku z nową linią w nazwie.
Michael Durrant,

@Michael Durrant: Sugeruję, że dopuszczanie nowych linii w nazwach plików jest poważnym błędem systemowym.
jamesqf

@jamesqf - zobacz nowe wiersze w nazwach plików (szczególnie odpowiedź sml ).
don_crissti

0

Jeśli wykonasz cmd ls -a | grep ^ \. wtedy grep nie uważa „\” za znak specjalny i znaczenie „.” nie uciekaj.

Kiedy używamy cmd ls -a | grep „^ \.” następnie grep uważa „\” za znak specjalny i znaczenie „.” ucieka. To da wynik zgodnie z oczekiwaniami.

Jeśli chcesz używać grep cmd bez cudzysłowów, powinieneś również unikać znaku „\”. Możesz oczekiwać wyniku bez podwójnych cudzysłowów, wykonując następujące polecenie. ls -a | grep ^ \\.

Aby uzyskać szczegółowe informacje na temat znaczenia znaków specjalnych w Regex, zapoznaj się z poniższym linkiem. http://www.regular-expressions.info/quickstart.html

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.