Перенаправлення вмісту файлу на команду “echo”


41

У мене є файл з ім'ям my_file.txt, вміст якого є лише рядком Hello. Як я можу перенаправити його вміст на команду echo?

Я знаю , що є команди less, cat, more... але мені потрібно зробити це з echo.

Я спробував це:

$ cat my_file.txt | echo

а також це:

$ echo < my_file.txt

Але в обох випадках у stdout відображається лише порожня, а не вміст my_file.txt.

Як я міг це зробити?


7
Чому ви наполягаєте на використанні echo?
Кевін

7
@Kevin, мабуть, врешті-решт, він хоче розширити послідовність аварійних файлів ANSI C ( \n, b...) у файлі, що було б дійсним використанням echo(принаймні стандарту echo). Або, мабуть, він хоче зрозуміти, чому це не працює так. У будь-якому випадку, немає підстав для заборони на ІМО.
Стефан Шазелас

3
Я прийшов сюди, тому що мені було цікаво, чому це не працює, коли я відлучую <file.txt. Здається, що питання, що є в SE, є розумним, відповідь була дуже корисною. +1 від мене.
нейронет

Відповіді:


53

Ви можете перенаправити все, що хочете, echoале з цим нічого не вийде. echoне читає його стандартний ввід. Все, що він робить, - це записати на стандартний висновок свої аргументи, розділені символом пробілу та завершені символом нової лінії (а також з деякими echoреалізаціями з деякими послідовностями втечі в них розширені та / або аргументи, що починаються з -можливого трактування як варіанти).

Якщо ви хочете echoвідобразити вміст файлу, вам слід передати цей вміст як аргумент echo. Щось на зразок:

echo "$(cat my_file.txt)"

Зверніть увагу , що $(...)смуги тягнеться символ нового рядка з з виходу цієї catкоманди, і echoдодає одну задні.

Також зауважте, що крім zsh, ви не можете передавати символи NUL в аргументах команди, так що вище, як правило, не працюватиме з бінарними файлами. yashтакож буде видалено байти, які не входять до складу дійсних символів.

Якщо причина для бажання зробити це тому , що ви хочете , echoщоб розширити \n, \b, \0351... екранують послідовності в файлі (в UNIX сумісні echoреалізації роблять, але не всі ), то ви б краще використовувати printfзамість :

printf '%b\n' "$(cat my_file.txt)"

На противагу цьому echo, цей портативний портативний і не матиме проблем, якщо вміст файлу починається з -.


В якості альтернативи $(cat file), з ksh, zshі bash, можна також зробити:$(<file) . Це спеціальний оператор, за допомогою якого оболонка на відміну від catзчитування вмісту файлу для компенсації розширення. Він все ще позбавляє останніх рядків і задавлюється на байти NUL, за винятком в zsh. У тому bash, що все ще формує додатковий процес. Також зауважте, що одна відмінність полягає в тому, що ви не помилитесь, якщо спробуєте прочитати файл типу каталогу таким чином. Також, хоч $(< file)це особливе значення, $(< file; other command)це не (в zsh, коли не емуляція іншої оболонки, яка все-таки розширила б вміст file, запустивши неявну $READNULLCMD команду (як правило, пейджер)).


3
В обох Баш і ЗШ ви можете пропустити catі просто оболонка читати безпосередньо: echo "$(<my_file.txt)".
Кевін

1
Так, з ksh , zsh та bash можна використовувати $(<filename).
Димитре Радулов

Дуже дякую, ось що мені було потрібно, і це спрацювало! :-)
danielmbcn

@Kevin, Димитре, додано зараз.
Стефан Шазелас

4

Додаючи до інших відповідей, ви можете також спробувати перенаправлення вводу замість cat

echo $(<my_file.txt)

або

echo `<my_file.txt`

$()і `` виконують те ж саме, вони виконують команди всередині своєї області дії і дають вихід оболонці так, як ніби це було дано користувачем. Єдина різниця між цими двома полягає в тому, що $ () може бути рекурсивним і `` не може бути рекурсивним.


2

Проста відповідь: ви не можете. echo(будь то вбудована оболонка або звичайний двійковий), вона не обробляє стандартний вхід - це лише один спосіб.


Питання в тому, чому ви насправді хотіли б це зробити?
петерф

2

Як було сказано,

Якщо ви хочете echoвідобразити вміст файлу, вам слід передати цей вміст як аргументecho

Наприклад, ви можете це зробити так xargs(зважаючи на те, що вам потрібно включити інтерпретацію зворотної косої риски ):

$ cat my_file.txt | xargs echo -e

Або просто те, що ви запитували (без тлумачення послідовностей уникнення ):

$ cat my_file.txt | xargs echo

Однак зауважте, що при використанні xargs echo(те саме, що xargsbtw, як echoі команда за замовчуванням), echoбуде запущена команда з файлової системи, а не вбудована echoкоманда оболонки . Також зауважте, що xargsочікує, що його введення буде в дуже специфічному форматі (де пробіли, нові рядки, котирування, зворотні риски мають особливе значення). catтут не має особливого сенсу, оскільки є лише один файл для об'єднання (такий же, як < file.txt xargs echo. Зверніть увагу, що сумісні echoз Unix s роблять зворотний -eecho -e
нахил у зворотному куті

0

У bash також має працювати наступне:

echo `cat my_file.txt`

Частина в беккетках замінюється результатом цієї команди, тобто в цьому випадку замінюється вмістом файлу.


Правда, backtikks працює як $( . . . ). Люди, які користуються, $()зазвичай віддають перевагу їм, оскільки ви можете їх гніздо. Це питання давнє, однак набагато задовольнити відповідати на запитання, на які вже не відповіли!
Закон29

Не зовсім. Є тонка різниця. Коли використовується зворотна галочка, зворотна косою рисою зберігається буквальне значення, за винятком випадків, коли слідує $, `або \. Перша зворотна галочка, якій не передує зворотна риса, завершує команду. При використанні форми $ (,,,) всі символи між дужками складають команду.
fpmurphy

Оскільки ця заміна команди не цитується, до неї буде застосовано оператор split + glob. Наприклад, якщо він my_file.txtмістить *, він буде надрукувати список імен файлів у поточному каталозі.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.