Прежде чем grep увидит аргумент командной строки, этот аргумент анализируется оболочкой. Для оболочки * - это подстановочный знак для «всех файлов без точек в текущем каталоге». Поскольку оболочка сначала обрабатывает аргумент, ваша строка превращается в это:
cat abcd | grep abcd otherfile zfile
(при условии, что эти три файла находятся в вашем текущем каталоге). Это то, что grep видит из своих аргументов, но это не то, что вы хотите.
Вместо этого вы можете поместить шаблон для grep в кавычки, чтобы он не обрабатывался оболочкой:
cat abcd | grep "*"
Это лучше, но все же не то, что вы хотите: grep использует регулярные выражения, а не подстановочные знаки в стиле оболочки. Звездочка для grep означает «0..n повторений предыдущего символа» - символ, который вы не указали. Близко, но не сигара.
Если вам нужен "любой" шаблон, вы ищете «0..n повторений произвольного символа». Последний представлен точкой ('.') В регулярных выражениях:
cat abcd | grep ".*"
Это то, что вы искали.
Изменить: другой случай легче объяснить. С grep "" вы ищете пустую строку, которая присутствует в качестве подстроки в любой строке.