grep
кажется сломанным на моей машине. Переустановка не помогает. Перезагрузка не помогает. Первые две строки создают файл, содержащий произвольный текст, а ввод завершается символом control-D.
ls -1
означает список в одном столбце. Пример следует ...
> cat > file0.txt
asdf
> cp file0.txt file1.txt
> ls -1
file0.txt
file1.txt
> ls -1 | grep f*
>
Прежде чем столкнуться с этой проблемой, я допустил ошибку, вызвав grep с непревзойденной цитатой, но я не понимаю, как эта проблема может пережить перезагрузку.
Пример непревзойденной цитаты ...
ls -1 | grep 'file* | wc
В этом примере список каталогов передается по каналу grep, который передает в программу счетчика строк, слов и байтов wc
.
grep
не использовал вывод ls
всегда.Когда Вы работаете grep f*
в ситуации, где Ваша оболочка расширяется f*
к двум или больше аргументам, grep
полагает, что все кроме одного из них как названия файлов открываются и читают. Когда grep
чтения из именованных файлов, его поведение по умолчанию чтения из стандартного входа не применяется, таким образом, это не считывает данные, переданные по каналу в него от другой команды.
Ваш grep
программа не повреждается, и поведение, которое Вы наблюдали, является корректным и ожидаемым поведением, которое является почему переустановка grep
и перезагрузка не изменила его. Детали следуют.
grep f*
не передал аргумент f*
к grep.grep
никогда не видел текст f*
. Как Soren A говорит, f*
шарик. Шарики рассматривает особенно Ваша оболочка. Поскольку f*
не был заключен в кавычки, оболочка развернула его на названия файлов в текущем каталоге, которые запускаются с f
. Каждое такое имя было передано grep
как отдельный аргумент. (Этот вид расширения оболочки известен по-разному как globbing, расширение имени файла и расширение пути.)
На основе Вашего описания существует точно два файла, которые соответствуют f*
шарик: file0.txt
и file1.txt
. Так как это - эти только два файла в текущем каталоге, имена которого запускаются с f
, параметры командной строки передали grep
от выполнения grep f*
точно то же как переданные ему от выполнения grep file0.txt file1.txt
. Если необходимо было добавить больше таких файлов к каталогу, то grep f*
передал бы больше, чем те два имен файлов как аргументы grep
, но file0.txt
и file1.txt
был бы все еще включен среди них.
ls
вывод к grep
, но grep
не читал из канала.Канал соединяет стандартный вывод одной команды к стандартному входу другого. Как cat
и много других команд, grep
принимает вход двумя способами:
Можно передать его имена файлов как параметры командной строки, и это будет читать из тех файлов. Первый аргумент неопции grep
шаблон, но последующие аргументы неопции рассматривают как имена файлов, от которых будет взят вход.
(Вы не пытаетесь передать несколько шаблонов grep
, но если бы Вы были, то Вы могли бы использовать -e
опция, операнд которой всегда рассматривают как шаблон.)
Вы не можете передать аргументы имени файла, и это будет читать из своего собственного стандартного входа. Это - ситуация, в которой эффективно передать по каналу к grep
. Это - только в отсутствие аргументов имени файла это grep
чтения от стандартного входа вообще.
Поэтому возможно использовать grep
искать один или несколько файлов, без него блокирование и ожидание Вас для ввода входа в терминал. Когда Вы передаете по каналу к grep
, дополнительный вход, который не имел бы никакого смысла для grep
использовать прибывает из команды на левой стороне канала, а не от Вашего терминала. grep
все еще не использует его, и это - хорошая вещь.
(Вы не пытаетесь вызвать grep
для чтения стандартного входа в дополнение к одному или нескольким именованным файлам, но если Вы были, Вы могли бы передать его -
аргумент.)
Поскольку у Вас есть два файла в текущем каталоге, имена которого запускаются с f
, шарик f*
расширяется до двух аргументов. Первое, file0.txt
, используется в качестве шаблона. Второе, file1.txt
, взят для именования входного файла. Поскольку grep
дан аргумент, указывающий входной файл, первая из этих двух ситуаций, описанных выше, применяется ("Можно передать его имена файлов как параметры командной строки"). Так grep
никогда чтения от стандартного входа и никогда не используют вывод ls
.
Выражение grep f*
в Вашем случае, будет расширен до grep file0.txt file1.txt
оболочкой.
По-видимому, нет никакой строки с file0.txt
в файле file1.txt.
Я знаю, что это не то, что Вы хотели, но это, как это работает.
:~$ mkdir test
:~$ cd test/
:~/test$ touch f1
:~/test$ touch f2
:~/test$ set -x
:~/test$ ls | grep f*
+ ls --color=auto
+ grep --color=auto f1 f2
ls | grep 'f*'
плохая форма.
ls f*
должен быть предпочтен.
При использовании более сложных regex шаблонов переключитесь на egrep
/grep -E
.
В то время как я здесь, cat
редко необходим. tac
100x более полезен, чем cat
. cat
злоупотребление является серьезной проблемой о подобных Unix системах.;)
*
специальный символ, который свободно интерпретируется как новая команда / инструкция. Вы хотите поместить a \
перед ним:
ls -1 | grep f\*
Однако то, что Вы, вероятно, хотите, должно получить все файлы, запускающиеся с f
вместо ВСЕХ файлов, содержащих f
так используйте другой специальный символ вместо этого:
ls -1 | grep ^f
^
дает grep команду находить строки, запускающиеся с f
.