2016-05-29 2 views
-4

если я сделать Ls выход: enter image description hereПочему ls | grep * ничего не отображает?

но если я делать Ls | Grep комплекс * или ll | grep complex* или даже ll | grep * или ll | grep * | less выход всегда: enter image description here

Это сбивает с толку меня.

Я хочу получить список всех файлов, начинающихся с complex* FYI if '*' == что угодно.

+2

Поскольку оболочка расширяет '*'. Если вы хотите получить список всех файлов, начинающихся с «complex *», которые будут 'ls complex *'. –

+0

Вставьте 'echo', чтобы узнать, что делает bash с вашей второй командой:' ls | echo grep * ' – Cyrus

+0

Хуже того, если файл' complex_assignment_other.c' содержит строку с фразой 'complex_assignment.c', (например,' // эта функция определена в файле complex_assignment.c'), эта строка будет напечатана на терминале. – anishsane

ответ

1

По умолчанию * предназначенный для [ globbing ].

Если у вас есть файл с именем * или один содержащий *, вы могли бы сделать

ls | grep \* 

или

ls | grep '*' 

Если вы ищете в файлах буквальном * вы могли бы сделать:

grep '*' * # second will glob all the files in the current dir. 

Если вы хотите использовать все файлы, которые имеют слово Complex _plus_something сделать:

grep -E '\<Complex[_[:alnum:]]+' * 

Здесь + для одного или более и \< совпадает с пустой строкой в ​​начале слова :-)

+0

Да, спасибо большое, я пропустил цитаты – hungryWolf

+0

Заключительный'. * 'В последнем примере совершенно лишний; см. мой ответ для подробного объяснения. – tripleee

+0

ОК, спасибо человеку – hungryWolf

3

вы ищете для:

ls | grep 'complex.*' 

или, лучше:

ls complex* 
+0

Спасибо, много карты, что за ошибка: p – hungryWolf

+0

Я думаю, что все сделали почти эту точную ошибку один или два раза;) – webb

1

Чтобы упростить мое объяснение, я не буду говорить о скрытых файлах.

Потому что ваша команда не означает, чего вы пытаетесь достичь.

* Очень особенный для bash и не имеет значения, которое вы думаете. Это символ, который оболочка заменит всеми именами файлов, которые он может соответствовать в текущем каталоге. Пример:

[email protected]:~/foo$ ls 
[email protected]:~/foo$ touch foo 
[email protected]:~/foo$ ls 
foo 
[email protected]:~/foo$ ls | grep * 
foo 

% выше эквивалентно $ ls | grep foo

[email protected]:~/foo$ touch bar 
[email protected]:~/foo$ ls | grep * 

% выше эквивалентно $ ls | grep bar foo, он будет выводить что-то, если слово «бар» находится В в файл foo.

См там пример с большим количеством файлов:

[email protected]:~/foo$ touch bar foo foobar 
[email protected]:~/foo$ echo "bar" > foo 
[email protected]:~/foo$ echo "bar" > foobar 
[email protected]:~/foo$ ls | grep * 
foo:bar 
foobar:bar 

Теперь, чтобы сделать то, что вы хотите достичь, вы можете использовать * в свою пользу:

[email protected]:~/foo$ ls foo* 
foo foobar 

Но если это каталог, который соответствует вашему исследованию, он перечислит его содержимое.

[email protected]:~/foo$ mkdir foodir 
[email protected]:~/foo$ for i in {0..10}; do touch "foodir/$i"; done 
[email protected]:~/foo$ ls foo* 
foo foobar 

foodir: 
0 1 10 2 3 4 5 6 7 8 9 

Таким образом, вы можете использовать опцию не -d, чтобы перечислить их содержание:

[email protected]:~/foo$ ls -d foo* 
foo foobar foodir 

Но если ваш поиск становится все более сложным, я могу только совет использовать более мощный инструмент, как найти.

Это один использует подстановку (* я объяснил выше)

[email protected]:~/foo$ find . -type f -name "foo*" 
./foo 
./foobar 

Это один использует регулярное выражение, но это инструмент, который вам нужно изучить немного, чтобы быть в состоянии справиться без потери волос:

[email protected]:~/foo$ find . -type f -regex ".*/foo[^/]*$" 
./foo 
./foobar 

Чтобы объяснить немного, выше поиск текущего каталога (.) для файлов только (типа F), которые соответствуют определенному шаблону (-regex "/Foo [^ /] $").

Этот шаблон «все, за которым следует slash foo, за которым следует что-либо, кроме слэша, до конца файла».

+0

ха-ха! красивый abt волосы: D – hungryWolf

+0

и приятное объяснение тоже. Большое спасибо за ваши усилия. – hungryWolf

1

У вас есть две ошибки: * не означает «ничего» в регулярных выражениях, а потому, что вы его не процитировали, оболочка расширила его.

Если у вас есть три файла, результат ls | grep * после маски расширения нечто вроде

ls | grep bar baz foo 

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

Теперь регулярное выражение, которое вы использовали для поиска comple в любой точке входа (x* означает ноль или более вхождений x, если равны нулю, то выражение будет соответствовать, и это не мешает соответствие, скажем, incomplete , поэтому вы можете как-то пропустить это). Правильное выражение: ^complex, чтобы найти это слово только в начале строки (не забывайте кавычки: ^ также является метасимволом оболочки) или просто complex, чтобы найти его в любом месте на линии.

Если точка просто для перечисления, вам не нужны grep или обычные выражения вообще, или ls, либо!

echo complex* 

покажет имена всех соответствующих файлов, или если вы хотите по одному в строке,

printf '%s\n' complex* 

(Это также более надежной, так вообще лучший подход. Избегайте как ls и echo в сценариях, если сможете.)

Чтобы перебрать совпадающие файлы, вы не можете надежно использовать ls.

for f in complex*; do 
    printf '%s\n' "$f" 
done 

Как частный случай, grep '*' ищет буквальную звездочку. Некоторые средства регулярного выражения (по праву) терпят неудачу с сообщением об ошибке для недействительного регулярного выражения (в том числе * BSD grep, специальный случай находится в GNU grep).

+0

узнал много чего, отныне я не буду использовать ls и echo в своих сценариях bash, спасибо за помощь – hungryWolf

Смежные вопросы