У меня есть список ".c" (c файлы) в текущем каталоге.

Я должен найти все файлы .c в текущем каталоге.

Команда, которую можно использовать id ls * .c

Но, другой способ - использовать grep.

так что если я дам

 ls | grep *.c

Он не возвращает никакого результата для этой команды, тогда как для других типов файлов, таких как ".java", ".txt", он дает ожидаемые результаты.

Есть ли какое-то особое значение для "* .c" в команде grep? Или я могу знать причину такого поведения?

6 ответов6

7

*.c является шаблоном glob, а grep ищет регулярные выражения.

Вы хотите ls | grep '\.c$' если вы хотите найти все файлы, заканчивающиеся на .c .

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

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

Чтобы убедиться, что вы соответствуете только в конце имени файла, вы используете $ , который соответствует концу строки.

3

Или используйте поиск, а затем получите список при необходимости, например,

find . -name "*.c" -exec ls -al {} \;

Найти очень полезно.

0

grep ищет содержимое файлов по вашему REGEX, а не по именам файлов.

0

Пожалуйста, попробуй:

ls | grep '\.c$'

RegExp "*" не требуется

0

Вам нужно процитировать звездочки:

ls | grep "*.c"

или оболочка bash собирается развернуть его и выполнить что-то вроде:

ls | grep 1.c 2.c 3.c

(предположим, у вас есть файлы с именами 1.c , 2.c , 3.c в текущем каталоге).

что не даст ожидаемого результата.

Что на самом деле будет делать, так это искать в содержимом 2.c и 3.c и показывать строки, в которых есть строка 1.c , которых, вероятно, нет, и поэтому вы получаете пустой вывод.

(Я просто объясняю, почему вы получили пустой вывод, как говорили другие, *.c не является допустимым регулярным выражением)

0

grep "* .c" будет искать буквально строку "* .c", то есть строку "звездочка точка c", не расширяя ее, чтобы обозначать "все файлы с расширением .c", поэтому она не находит что-нибудь в выводе "ls":

# Touch BC

# ls -1 | grep "* .c"

результат пуст.

Если вы хотите расширение, вы должны использовать egrep (extended grep), который выполняет регулярные выражения. Но здесь они немного разные:

# ls -1 | egrep ".*.c"
b.c

то есть регулярное выражение это:* .c (любой символ, не являющийся символом новой строки, умноженный на ноль или более раз, любой символ, не являющийся символом новой строки [вы можете избежать буквального обозначения "точка"], "c")

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .