Відповіді:
Це не працює, тому що 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):
Складені команди Складені команди
є одним із наступних. У більшості випадків список в описі команди може бути відокремлений від решти команди одним або декількома новими рядками, а після цього крапкою з комою може слідувати новий рядок.
(список)список виконується в середовищі додаткової оболонки (див. КОМАНДУ ВИКОНАВЧОГО ЕКОЛОГІЇ нижче). Змінні призначення та вбудовані команди, які впливають на середовище оболонки, не залишаються в силі після завершення команди. Статус повернення - це статус виходу зі списку.
{список;}список просто виконується в поточному середовищі оболонки. список повинен бути завершений новим рядком або крапкою з комою. Це відомо як команда групи . Статус повернення - це статус виходу зі списку . Зауважте, що на відміну від метахарактерів
(і),{і}є зарезервованими словами, вони повинні виникати там, де дозволено розпізнавати зарезервоване слово. Оскільки вони не викликають розрив слова, їх потрібно відокремити від списку пробілом або іншим метахарактером оболонки.
Перший варіант (середовище додаткової оболонки) має купу побічних ефектів, більшість з яких не всі стосуються вашого сценарію; однак, якщо все, що вам потрібно, перенаправлення виводу з команд - це варіант №2 (команда групи).
( echo "abc"; cat 1.txt ) > 2.txt
Ви передали ехо-виведення коту, але кіт не мав користі для введення даних і проігнорував це. Тепер команди виконуються одна за одною, а їх вихід групується (в дужках) і спрямовується в 2.txt.
bash(1), він описує поведінку, яку повинна підтримувати кожна сумісна з POSIX оболонка.
У будь-якій оболонці POSIX ви можете використовувати заміну команд, щоб використовувати cat fileяк вхід для echo:
echo $(cat file1.txt) "This Too"
У Bash ви можете використовувати підстановку процесу та використовувати echo як інший "файл" для cat, як у:
cat file1.txt <(echo This Too)
а потім трубуйте або перенаправляйте вихід, як вважаєте за потрібне.
Як і кожна інша відповідь, кішка ігнорує stdin, якщо у нього є файл, який потрібно подивитися. (Мені також подобаються відповіді Даніеля та 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 з >> Після цього && скаже йому виконати наступний набір команд, який введе кодування 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файл; це неприпустимо.
echoперед перед catзразком команди, я вважаю, що він ніколи точно, явно , не говорить, що він хоче виводити з ехо перед вміст вхідного файлу. Просто здається, що більшість людей так трактували це. (2) 1.txt- вхідний файл. Питання нічого не говорить про зміни 1.txt. Те, що вхідні файли не слід змінювати, само собою зрозуміло.
catчитати лише зі стандартного введення, якщо у них немає аргументів імені файлів.