Как я могу выполнить две команды на одном входе, не вводя этот ввод дважды?
Например, команда stat много говорит о файле, но не указывает его тип файла:
stat fileName
Команда file сообщает тип файла:
file fileName
Вы можете выполнить это в одну строку следующим образом:
stat fileName ; file fileName
Тем не менее, вы должны ввести fileName дважды.
Как вы можете выполнить обе команды на одном и том же входе (не вводя ввод или переменную ввода дважды)?
В Linux я знаю, как транслировать выходные данные, но как вы транслируете входные данные?
command-line
Lonniebiz
источник
источник
<
(ввод из файла на левую сторону) или|
(ввод из потока на правую сторону). Есть разницаyank-last-arg
команда (сочетание клавиш по умолчаниюMeta-.
илиMeta-_
;Meta
часто это леваяAlt
клавиша) скопирует последний параметр из предыдущей командной строки в текущую. Таким образом, после выполненияstat fileName
вы набираетеfile [Meta-.]
и не нужно вводить этоfileName
снова. Я всегда этим пользуюсь.<
и>
есть перенаправление , а не пайпинг . Конвейер соединяет два процесса, а перенаправление просто переназначает stdin / stdout.Ответы:
Вот еще один способ:
Пример:
Это работает в
bash
иzsh
. Это также работаетmksh
иdash
только в интерактивном режиме. В AT & T ksh это работает только тогда, когда онfile "$_"
находится на линии, отличной от тойstat
.источник
!$
не будет работать, потому что!$
расширяется до последнего слова последнего события истории (то есть ранее введенной командной строки, а не команды stat).Вероятно, я собираюсь получить мои пальцы за это, вот хакерская комбинация расширения bash brace и eval, которая, кажется, добивается цели
источник
csh
, а неbash
.bash
скопировал это изksh
. Этот код будет работать во всех csh, tcsh, ksh, zsh, fish и bash.eval
? (со ссылкой на топ комментариев)С помощью
zsh
вы можете использовать анонимные функции:С
es
лямбдами:Вы также можете сделать:
(делая
stat
первый, какfile
обновит время доступа).Я сделаю:
хотя, для этого и нужны переменные.
источник
{ stat -; file -;} < filename
это магияstat
Должны ли проверять, чтобы его стандартный ввод был подключен к файлу, и сообщать об атрибутах файла? Предположительно не продвигает указатель на stdin, поэтому позволяетfile
stat -
говорит,stat
чтобы сделатьfstat()
на его fd 0.{ $COMMAND_A -; $COMMAND_B; } < filename
Вариант не будет работать в общем случае , если $ COMMAND_A фактически читает любой входной сигнал; Например{ cat -; cat -; } < filename
, напечатает содержимое файла только один раз.stat -
обрабатывается специально начиная с coreutils-8.0 (октябрь 2009 г.), в версиях, предшествующих этому, вы получите ошибку (если у вас нет файла, вызванного-
из предыдущего эксперимента, и в этом случае вы получите неправильные результаты ...)stat -f0
вместо этого.Все эти ответы кажутся мне сценариями в большей или меньшей степени. Для решения, которое на самом деле не требует сценариев и предполагает, что вы сидите за клавиатурой и набираете текст в оболочке, вы можете попробовать:
По крайней мере, в bash, zsh и ksh, в режимах vi и emacs, нажатие Escape и подчеркивание вставляет последнее слово из предыдущей строки в буфер редактирования для текущей строки.
Или вы можете использовать подстановку истории:
В bash, zsh, csh, tcsh и большинстве других оболочек
!$
заменяется последним словом предыдущей командной строки при анализе текущей командной строки.источник
Esc _
? Можете ли вы связать с официальной документацией?Я нашел способ сделать это достаточно просто, используя xargs, он берет файл / канал и преобразует его содержимое в аргументы программы. Это может быть объединено с тройником, который разделяет поток и отправляет его двум или более программам. В вашем случае вам нужно:
В отличие от многих других ответов, это будет работать в bash и большинстве других оболочек под Linux. Я предполагаю, что это хороший вариант использования переменной, но если вы абсолютно не можете ее использовать, то это лучший способ сделать это только с помощью конвейеров и простых утилит (при условии, что у вас нет особо красивой оболочки).
Кроме того, вы можете сделать это для любого количества программ, просто добавив их таким же образом, как эти две после тройника.
РЕДАКТИРОВАТЬ
Как указывается в комментариях, в этом ответе есть несколько недостатков, во-первых, это возможность чересстрочного вывода. Это можно исправить так:
Это заставит команды выполняться по очереди, и выходные данные никогда не будут чересстрочными.
Вторая проблема состоит в том, чтобы избежать замены процесса, которая недоступна в некоторых оболочках, это может быть достигнуто путем использования tpipe вместо tee следующим образом:
Это должно переноситься практически на любую оболочку (я надеюсь) и решает проблемы в других комментариях, однако я пишу последний из памяти, так как в моей нынешней системе нет доступных tpipe.
источник
ksh
(не в публичном доступе),bash
иzsh
. Обратите внимание, чтоstat
иfile
будет работать одновременно, поэтому, возможно, их выходные данные будут переплетены (я полагаю, вы используете| cat
принудительную буферизацию вывода для ограничения этого эффекта?).Этот ответ похож на пару других:
В отличие от других ответов, которые автоматически повторяют последний аргумент из предыдущей команды, этот требует подсчета:
В отличие от некоторых других ответов, это не требует кавычек:
или
источник
Это похоже на пару других ответов, но является более переносимым, чем этот, и намного проще, чем этот :
или
в котором
sh
назначен$0
. Несмотря на то, что для ввода текста требуется больше трех символов, эта (вторая) форма предпочтительнее, потому что$0
это имя, которое вы даете этому встроенному сценарию. Он используется, например, в сообщениях об ошибках в оболочке для этого сценария, например , когдаfile
илиstat
не может быть найден или не может быть выполнен по любой причине.Если вы хотите сделать
для произвольного числа файлов сделайте
который работает, потому что
"$@"
эквивалентен"$1" "$2" "$3" …
.источник
$0
имя, которое вы хотите дать этому встроенному скрипту. Например, он используется в сообщениях об ошибках оболочкой для этого скрипта. Например, когдаfile
илиstat
не могут быть найдены или не могут быть выполнены по любой причине. Итак, вы хотите что-то значимое здесь. Если не вдохновили, просто используйтеsh
.Я думаю, что вы задаете неправильный вопрос, по крайней мере, для того, что вы пытаетесь сделать.
stat
иfile
команды принимают параметры, которые представляют собой имя файла, а не его содержимое. Позднее команда выполняет чтение файла, идентифицируемого указанным вами именем.Предполагается, что канал имеет два конца, один используется в качестве входных данных, а другой - в качестве выходных, и это имеет смысл, так как вам, возможно, придется выполнять разную обработку в процессе работы с различными инструментами, пока вы не получите нужный результат. Сказать, что вы знаете, как передавать данные по выходам, но не знаете, как передавать данные по входам, в принципе неправильно.
В вашем случае вам вообще не нужен канал, поскольку вы должны предоставить входные данные в форме имени файла. И даже если эти инструменты (
stat
иfile
) будут читать stdin, труба здесь снова не актуальна, так как ввод не должен изменяться каким-либо инструментом, когда он попадает во второй.источник
Это должно работать для всех имен файлов в текущем каталоге.
источник
}
... символов и не начинаются с-
. Некоторыеprintf
реализации (zsh, bash, ksh93) имеют%q
. При томzsh
, что это может быть:printf 'stat %q; file %1$q\n' ./* | zsh
sed
s///
я думаю, но это о сфере действия - и если люди помещают это в свои имена файлов, они должны использовать окна.*
дважды . Вы могли бы также сказатьstat -- *; file -- *
.*
расширяется. Расширение на*
плюс две команды для каждого аргумента в*
это вход. Видеть?printf commands\ %s\;shift *
Здесь есть несколько разных ссылок на «входные данные», поэтому я приведу несколько сценариев с пониманием этого в первую очередь. Для быстрого ответа на вопрос в кратчайшей форме :
Вышеприведенное будет выполнять статистику для тестового файла, принимать (перенаправлять) его STDOUT и включать его в следующую специальную функцию (часть <()), а затем выводить окончательные результаты, что бы это ни было, в новый файл (выходной файл). Файл вызывается, затем на него ссылаются встроенные команды bash ($ 1 каждый раз после, пока вы не начнете новый набор инструкций).
Ваш вопрос великолепен, и есть несколько ответов и способов сделать это, но он действительно меняется в зависимости от того, что вы делаете конкретно.
Например, вы можете зациклить это, что довольно удобно. Обычное использование этого в псевдо-коде мышления:
Принимая это и расширяя эти знания, вы можете создавать такие вещи, как:
Это выполнит простую команду ls -A в вашем текущем каталоге, а затем покажет цикл в цикле по каждому результату от ls -A до (и здесь это сложно!) Grep «thatword» в каждом из этих результатов и выполнит только предыдущий printf (красным), если он действительно обнаружил файл с этим словом. Он также запишет результаты grep в новый текстовый файл files_that_matched_thatword.
Пример вывода:
Все это просто напечатало результат ls -A, ничего особенного. На этот раз добавьте что-нибудь для grep:
Теперь перезапустите это:
Хотя, возможно, более утомительный ответ, чем вы ищете в настоящее время, я считаю, что хранение таких удобных заметок принесет вам гораздо больше пользы в будущих начинаниях.
источник