Странное поведение «ls -a | grep ^ \. "

10

Я хотел перечислить содержимое pwd и отображать только файл, начинающийся с точки. Я пытался, ls -a | grep ^\.но я не могу понять, почему вывод содержит также файлы, которые не начинаются с точки. Например:

Pictures
.pip
.pki
.profile
projects
Public

Я знаю, что могу достичь того, чего хочу, ls -ld .*мне просто любопытно такое поведение grep, которое я не могу объяснить.

пс-Окс
источник
Почему бы просто не ls -d .*перечислить все файлы, начинающиеся с .?
Бармар
Предупреждение: никогда не передавайте вывод команды ls в другую команду. Вместо этого используйте поиск. У меня слишком много идеосинкразий, чтобы доверять. Смотрите: Pitfall 1 на mywiki.wooledge.org/BashPitfalls - это первое место! Остальная часть сайта тоже отличная.
Джо

Ответы:

20

Цитировать аргумент grep, таким образомls -a | grep '^\.'

Причина этого заключается в том, что оболочка обрабатывает \.и превращает ее обратно в обычный ., который grepзатем обрабатывается как подстановочный знак из одного символа. В случае сомнений всегда заключайте в кавычки строку, которая содержит (или может содержать) символ, особенный для оболочки.

roaima
источник
Почему оболочка игнорирует \?
PS-aux
\ является escape-последовательностью, которая заставляет оболочку считать следующий символ буквальным. В этом случае grep ^\\.\\ обрабатывается оболочкой как одиночный обратный слеш, и снова grep обрабатывает одиночный обратный слеш, за которым следует точка как буквальная точка.
Авинаш Радж
11

Вам нужно поместить выражение grep в кавычки.

ls -a | grep '^\.'

Примечание: не анализируйте вывод lsкоманды .

Авинаш Радж
источник
Почему плохо разбирать вывод ls?
PS-aux
Из ссылки: В стандартном режиме, если стандартный вывод не является терминалом, ls отделяет имена файлов с символами новой строки. Это нормально, пока у вас нет файла с новой строкой в ​​названии.
Майкл Даррант
@ Майкл Даррант: Я бы предположил, что добавление новых строк в именах файлов является серьезной системной ошибкой.
jamesqf
@jamesqf - видеть новые строки в именах файлов (особенно ответ sml ).
don_crissti
0

Если вы выполните cmd ls -a | grep ^ \. тогда grep не считает "\" специальным символом и значением "." не спасайся

Когда мы используем cmd ls -a | grep "^ \." тогда grep рассматривает "\" как специальный символ и значение "." сбежал. Это даст вам результат, как и ожидалось.

Если вы хотите использовать grep cmd без кавычек, вам также следует экранировать символ "\". Вы можете ожидать результата без двойных кавычек, выполнив следующую команду. ls -a | grep ^ \\.

Подробнее о значении специальных символов в Regex см. По следующей ссылке. http://www.regular-expressions.info/quickstart.html

AVJ
источник