Используйте оператор Regex +
, чтобы указать один или несколько предшествующих токенов, в данном случае пробел. Таким образом, шаблон будет\+
:
echo "Ambari Server running" | grep -i "Ambari \+Server \+running"
Я бы посоветовал использовать класс символов [:blank:]
для соответствия любому горизонтальному пробелу, а не только простому пробелу, если вы не уверены:
echo "Ambari Server running" | grep -i "Ambari[[:blank:]]\+Server[[:blank:]]\+running"
С другой стороны, если вы хотите оставить только один пробел между словами, используйтеawk
:
echo "Ambari Server running" | \
awk '$1=="Ambari" && $2=="Server" && $3=="running" {$1=$1; print}'
$1=="Ambari" && $2=="Server" && $3=="running"
соответствует трем нужным полям
{$1=$1}
перестраивает запись с пробелом в качестве нового разделителя
{print}
распечатывает запись
Канал соединяет стандартный вывод процесса слева от стандартного ввода процесса справа. echo "file.txt ~/.Trash"
записывает file.txt ~/.Trash
на свой стандартный вывод, и конвейер делает эту строку доступной для mv
для чтения.
Тем не менее, mv
не читает из стандартного ввода в этот момент :, как следует из сообщения об ошибке, которое вы процитировали, вместо этого он ожидает получить по крайней мере два аргумента командной строки (один source
и один target
или один или несколько source
s и один directory
. Он жалуется, что ничего не видит, и выходит.
(Обратите внимание, что mv
не будет считывать данные со своего стандартного ввода, даже если вы вызовете его так, как он требует, например. работает echo foo | mv source dest
. Он использует стандартный ввод только тогда, когда ему необходимо взаимодействовать с пользователем, например, при запросе подтверждения ).
Действительно, не каждая программа читает со стандартного ввода. Использование стандартных потоков частью программ объясняется на их man
страницах ual. Утилиты POSIX имеют специальные разделы для «STDIN», «STDOUT» и «STDERR», в то время как другие версии менее формально организованы и, возможно, потребуется прочитать их полностью.
Никакие правила не определяют, как программа должна использовать стандартные потоки. Как указано в ответах на предложенную дублирующую цель , это в основном относится к семантике программы. Упрощая больше, чем немного,программы, которые имеют дело с потоками данных, как правило, используют их стандартный ввод/вывод, в то время как программы, которые имеют дело с объектами операционной системы (, файлами, каталогами, процессами, пользователями... ), как правило, вместо этого принимают только аргументы командной строки.
Наконец, подойдя к конкретному вопросу, ваши вопросы, кажется, вызывают :только подмножество *утилит nix, которые считывают со стандартного ввода, используют его для чтения команд . Только те, которые, вообще говоря, являются интерпретаторами :, в основном представляют собой (стандартные sh
, bash
, zsh
... )и утилиты, ориентированные на обработку текста (, хотя и не ограничиваются обработка текста; например. awk
, grep
, sed
... ), но и калькуляторы(bc
)и, конечно, другие, которые отказываются приходить мне в голову прямо сейчас.
Как и большинство инструментов, предназначенных для управления *nix-системами, mv
не предназначен для разбора строки на отдельные элементы. В обычном разделении задач это роль оболочки, которая, в свою очередь, вызывает такие инструменты, как mv
для выполнения конкретных действий (, основанных )на аргументах, индивидуальное значение которых хорошо определено (и часто делается понятно из документации, как вmv [-f | -i | -n] [-v] source target
).
Чтобы проиллюстрировать этот пункт :, хотя вы не можете сказать mv
, что делать через стандартный ввод, и вместо этого нужно ввести mv foo bar
, вы можете сделать echo "mv foo bar" | sh
. Интерпретатор sh
, который читает команды из стандартного ввода, если он не получает файловых аргументов, заботится об их синтаксическом анализе и вызывает mv
с двумя аргументами foo
и bar
.