Такие программы, как catчтение только из стандартного ввода, если они не имеют аргументов имени файла.
Бармар
Ответы:
23
Это не работает, потому что catпрограмме в вашей последовательности каналов не было дано указание прочитать echoвыходные данные программы из стандартного ввода.
Вы можете использовать -в качестве псевдо-имени файла для обозначения стандартного ввода для cat. С man catустановки msys2:
EXAMPLES
cat f - g
Output f's contents, then standard input, then g's contents.
Как отмечали другие, ваша оригинальная команда не работает, потому что cat 1.txtигнорирует ее стандартный ввод. Либо укажите, что это должен быть его первый аргумент ( cat - 1.txt), либо используйте перенаправление блоков для перенаправления echo abcиcat 1.txt вместе. Для остроумия:
{ echo abc; cat 1.txt; } > 2.txt
Соответствующая выдержка из руководства ( man bash):
Составные команды Составная
команда является одной из следующих. В большинстве случаев список в описании команды может быть отделен от остальной части команды одним или несколькими символами новой строки и может сопровождаться символом новой строки вместо точки с запятой.
(список)
Список выполняется в среде оболочки (см. ниже КОМАНДА ИСПОЛНИТЕЛЬНОЙ СРЕДЫ). Переменные и встроенные команды, которые влияют на среду оболочки, не остаются в силе после ее завершения. Статус возврата - это статус выхода из списка.
{список;}
Список просто выполняется в текущей среде оболочки.
список должен заканчиваться символом новой строки или точкой с запятой. Это называется групповой командой . Статус возврата - это статус выхода из списка . Обратите внимание, что в отличие от метасимволов (и ),
{и }являются зарезервированными словами, они должны встречаться там, где зарезервированное слово разрешено распознавать. Поскольку они не вызывают разрыв слова, они должны быть отделены от списка
пробелом или другим метасимволом оболочки.
Первый вариант (среда subshell) имеет множество побочных эффектов, большинство из которых, если не все, не имеют отношения к вашему сценарию; однако, если все, что вам нужно, - это перенаправить вывод нескольких команд, то здесь предпочтителен вариант № 2 (групповая команда).
Вы передали вывод эха в cat, но cat не использовал ввод и проигнорировал его. Теперь команды выполняются одна за другой, и их выходные данные группируются (круглые скобки) и направляются в 2.txt.
Этот ответ можно улучшить, объяснив, почему первоначальная попытка ОП не работает (и, следовательно, почему это необходимо).
Боб
1
<(command)Конструкция является продолжением Баша. Это не POSIX, поэтому вы не можете полагаться на него в сценариях, которые должны выполняться с /bin/sh.
Риальто поддерживает Монику
0
Просто предположение, но похоже, что у вас есть повторяемый процесс, который является хорошим кандидатом на псевдоним или функцию. Псевдонимы - это, как правило, короткие пути для вызова команд bash, таких как сокращение, в одном входном потоке в качестве аргумента / ов.
alias hg="history | grep"
Однако в этом случае функция будет более читабельной, поскольку вы объединяете несколько дискретных (2) входных потоков, а также несколько команд bash. У вас есть два аргумента, первый из которых является строкой, а другой - путем к файлу. В конце вы хотите, чтобы результат был записан в поток вывода stdout.
В командной строке CLI введите это:
# ecat()
{
echo ${1}
cat ${2}
}
Ваша функция называется ecat, которая запоминается.
Теперь вы можете ссылаться как
ecat "abc" 1.txt
Чтобы добавить, просто укажите другое назначение вывода для stdout:
ecat "abc" 1.txt >> 2.txt
Оператор перенаправления добавления '>>' добавит вывод в конец указанного файла.
Если вам это нравится, добавьте файл ~ / .bashrc для повторного использования.
declare -f ecat >> ~/.bashrc
Это также означает, что вы можете украшать и т. Д. В рамках определения вашей функции.
Также хорошая идея защитить файлы от перезаписи, добавив это в ~ / .bashrc
Как noclobberпредложение реагирует на поставленный вопрос? (Я также очень не убежден, что это хороший совет - изменение глобального поведения имеет тенденцию нарушать сценарии / советы / практики, созданные с учетом значений по умолчанию).
Чарльз Даффи
0
Следующий код также будет работать:
echo abc >> 1.txt && cat 1.txt > 2.txt
Вывод echo abc будет добавлен в 1.txt с помощью >>.
После этого && скажет ему выполнить следующий набор команд, который будет cat 1.txt, а затем выведет его в 2.txt . По сути, он добавляет вывод первой команды в 1.txt, а затем отправляет вывод 1.txt в 2.txt.
Если вы хотите, чтобы abc появлялся первым, вы можете использовать следующий код:
Это будет (1) положить abcв нижней части 2.txt; вопрос хочет это наверху. (2) изменения в 1.txtфайл; это неприемлемо.
G-Man говорит «Восстановить Монику»
Где это сказано? Ringger81 никогда не указывал, где в 2.txt он хотел, чтобы появился abc. Вы предполагаете вещи, о которых вопрос никогда не говорит.
Насир Райли
(1) Хорошо, вы подняли действительную точку на # 1. В то время как в вопросе упоминается «вывод из echo» перед «содержимым файла» в тексте, а затем помещается команда « echobefore» catв образце, я предполагаю, что он никогда точно и явно не говорит о том , что он хочет вывод из echo до содержимое входного файла. Просто кажется, что большинство людей интерпретируют это так. (2) 1.txtявляется входным файлом. Вопрос ничего не говорит о модификации 1.txt. Тот факт, что входные файлы не должны быть изменены, само собой разумеется.
G-Man говорит: «Восстановите Монику»
Я могу понять вашу мысль о том, чтобы не изменять файл импута. Мой второй код позволит достичь желаемого эффекта без этого.
Насир Райли
1
Открытие файла, добавление к нему, закрытие его , открытие его снова, добавление к нему снова ... почему вместо того, чтобы просто открыть его один раз и сохранить перенаправление на месте для обеих операций?
cat
чтение только из стандартного ввода, если они не имеют аргументов имени файла.Ответы:
Это не работает, потому что
cat
программе в вашей последовательности каналов не было дано указание прочитатьecho
выходные данные программы из стандартного ввода.Вы можете использовать
-
в качестве псевдо-имени файла для обозначения стандартного ввода дляcat
. Сman cat
установки msys2:Так что постарайтесь
вместо.
источник
Как отмечали другие, ваша оригинальная команда не работает, потому что
cat 1.txt
игнорирует ее стандартный ввод. Либо укажите, что это должен быть его первый аргумент (cat - 1.txt
), либо используйте перенаправление блоков для перенаправленияecho abc
иcat 1.txt
вместе. Для остроумия:Соответствующая выдержка из руководства (
man bash
):Первый вариант (среда subshell) имеет множество побочных эффектов, большинство из которых, если не все, не имеют отношения к вашему сценарию; однако, если все, что вам нужно, - это перенаправить вывод нескольких команд, то здесь предпочтителен вариант № 2 (групповая команда).
источник
Вы передали вывод эха в cat, но cat не использовал ввод и проигнорировал его. Теперь команды выполняются одна за другой, и их выходные данные группируются (круглые скобки) и направляются в 2.txt.
источник
bash(1)
его, он описывает поведение, которое должна поддерживать каждая POSIX-совместимая оболочка.Ваша команда
cat 1.txt
ничего не делает с выводомecho "abc"
.Вместо этого:
(echo "abc"; cat 1.txt) > 2.txt
запишет вывод обеих команд в 2.txt.источник
В любой оболочке POSIX вы можете использовать подстановку команд для использования в
cat file
качестве входных данных дляecho
:В Bash вы можете использовать подстановку процессов и использовать echo в качестве другого «файла» для
cat
, как в:а затем направьте или перенаправьте вывод, как считаете нужным.
Как и в любом другом ответе, cat игнорирует стандартный ввод, если у него есть файл для просмотра. (Мне тоже нравятся ответы Даниэля и mvw, +1 за них)
источник
<(command)
Конструкция является продолжением Баша. Это не POSIX, поэтому вы не можете полагаться на него в сценариях, которые должны выполняться с/bin/sh
.Просто предположение, но похоже, что у вас есть повторяемый процесс, который является хорошим кандидатом на псевдоним или функцию. Псевдонимы - это, как правило, короткие пути для вызова команд bash, таких как сокращение, в одном входном потоке в качестве аргумента / ов.
Однако в этом случае функция будет более читабельной, поскольку вы объединяете несколько дискретных (2) входных потоков, а также несколько команд bash. У вас есть два аргумента, первый из которых является строкой, а другой - путем к файлу. В конце вы хотите, чтобы результат был записан в поток вывода stdout.
В командной строке CLI введите это:
Ваша функция называется ecat, которая запоминается.
Теперь вы можете ссылаться как
Чтобы добавить, просто укажите другое назначение вывода для stdout:
Оператор перенаправления добавления '>>' добавит вывод в конец указанного файла.
Если вам это нравится, добавьте файл ~ / .bashrc для повторного использования.
Это также означает, что вы можете украшать и т. Д. В рамках определения вашей функции.
Также хорошая идея защитить файлы от перезаписи, добавив это в ~ / .bashrc
источник
"$1"
и"$2"
. В этом контексте фигурные скобки не приносят никакой пользы. См${name}
вовсе не означает , что вы думаете , что делает ... .noclobber
предложение реагирует на поставленный вопрос? (Я также очень не убежден, что это хороший совет - изменение глобального поведения имеет тенденцию нарушать сценарии / советы / практики, созданные с учетом значений по умолчанию).Следующий код также будет работать:
Вывод echo abc будет добавлен в 1.txt с помощью >>. После этого && скажет ему выполнить следующий набор команд, который будет cat 1.txt, а затем выведет его в 2.txt . По сути, он добавляет вывод первой команды в 1.txt, а затем отправляет вывод 1.txt в 2.txt.
Если вы хотите, чтобы abc появлялся первым, вы можете использовать следующий код:
источник
abc
в нижней части2.txt
; вопрос хочет это наверху. (2) изменения в1.txt
файл; это неприемлемо.echo
before»cat
в образце, я предполагаю, что он никогда точно и явно не говорит о том , что он хочет вывод из echo до содержимое входного файла. Просто кажется, что большинство людей интерпретируют это так. (2)1.txt
является входным файлом. Вопрос ничего не говорит о модификации1.txt
. Тот факт, что входные файлы не должны быть изменены, само собой разумеется.