Ответы:
Это не работает, потому что catпрограмме в вашей последовательности каналов не было дано указание прочитать echoвыходные данные программы из стандартного ввода.
Вы можете использовать -в качестве псевдо-имени файла для обозначения стандартного ввода для cat. С man catустановки msys2:
EXAMPLES
cat f - g
Output f's contents, then standard input, then g's contents.
Так что постарайтесь
echo "abc" | cat - 1.txt > 2.txt
вместо.
Как отмечали другие, ваша оригинальная команда не работает, потому что cat 1.txtигнорирует ее стандартный ввод. Либо укажите, что это должен быть его первый аргумент ( cat - 1.txt), либо используйте перенаправление блоков для перенаправления echo abc и cat 1.txt вместе. Для остроумия:
{ echo abc; cat 1.txt; } > 2.txt
Соответствующая выдержка из руководства ( man bash):
Составные команды Составная
команда является одной из следующих. В большинстве случаев список в описании команды может быть отделен от остальной части команды одним или несколькими символами новой строки и может сопровождаться символом новой строки вместо точки с запятой.
(список)Список выполняется в среде оболочки (см. ниже КОМАНДА ИСПОЛНИТЕЛЬНОЙ СРЕДЫ). Переменные и встроенные команды, которые влияют на среду оболочки, не остаются в силе после ее завершения. Статус возврата - это статус выхода из списка.
{список;}Список просто выполняется в текущей среде оболочки. список должен заканчиваться символом новой строки или точкой с запятой. Это называется групповой командой . Статус возврата - это статус выхода из списка . Обратите внимание, что в отличие от метасимволов
(и),{и}являются зарезервированными словами, они должны встречаться там, где зарезервированное слово разрешено распознавать. Поскольку они не вызывают разрыв слова, они должны быть отделены от списка пробелом или другим метасимволом оболочки.
Первый вариант (среда subshell) имеет множество побочных эффектов, большинство из которых, если не все, не имеют отношения к вашему сценарию; однако, если все, что вам нужно, - это перенаправить вывод нескольких команд, то здесь предпочтителен вариант № 2 (групповая команда).
( echo "abc"; cat 1.txt ) > 2.txt
Вы передали вывод эха в cat, но cat не использовал ввод и проигнорировал его. Теперь команды выполняются одна за другой, и их выходные данные группируются (круглые скобки) и направляются в 2.txt.
bash(1)его, он описывает поведение, которое должна поддерживать каждая POSIX-совместимая оболочка.
В любой оболочке POSIX вы можете использовать подстановку команд для использования в cat fileкачестве входных данных для echo:
echo $(cat file1.txt) "This Too"
В Bash вы можете использовать подстановку процессов и использовать echo в качестве другого «файла» для cat, как в:
cat file1.txt <(echo This Too)
а затем направьте или перенаправьте вывод, как считаете нужным.
Как и в любом другом ответе, cat игнорирует стандартный ввод, если у него есть файл для просмотра. (Мне тоже нравятся ответы Даниэля и mvw, +1 за них)
<(command)Конструкция является продолжением Баша. Это не POSIX, поэтому вы не можете полагаться на него в сценариях, которые должны выполняться с /bin/sh.
Просто предположение, но похоже, что у вас есть повторяемый процесс, который является хорошим кандидатом на псевдоним или функцию. Псевдонимы - это, как правило, короткие пути для вызова команд 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
set noclobber
"$1"и "$2". В этом контексте фигурные скобки не приносят никакой пользы. См ${name}вовсе не означает , что вы думаете , что делает ... .
noclobberпредложение реагирует на поставленный вопрос? (Я также очень не убежден, что это хороший совет - изменение глобального поведения имеет тенденцию нарушать сценарии / советы / практики, созданные с учетом значений по умолчанию).
Следующий код также будет работать:
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 появлялся первым, вы можете использовать следующий код:
echo abc >> 2.txt && cat 1.txt >> 2.txt
abcв нижней части 2.txt; вопрос хочет это наверху. (2) изменения в 1.txtфайл; это неприемлемо.
echobefore» catв образце, я предполагаю, что он никогда точно и явно не говорит о том , что он хочет вывод из echo до содержимое входного файла. Просто кажется, что большинство людей интерпретируют это так. (2) 1.txtявляется входным файлом. Вопрос ничего не говорит о модификации 1.txt. Тот факт, что входные файлы не должны быть изменены, само собой разумеется.
catчтение только из стандартного ввода, если они не имеют аргументов имени файла.