Перенаправление содержимого файла на команду «эхо»


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, по-видимому, в конечном итоге он хочет развернуть escape-последовательности ANSI C ( \n, b...) в файле, что будет допустимым использованием echo(по крайней мере, стандартным echo). Или, по-видимому, он хочет понять, почему это не работает таким образом. В любом случае, нет причин понижать рейтинг ИМО.
— Стефан Шазелас

3
Я пришел сюда, потому что мне было любопытно, почему это не работает, когда я делаю echo <file.txt. Кажется, разумный вопрос для SE, ответ был очень полезным. +1 от меня.
— нейронет

Ответы:


53

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

Если вы хотите 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, что все еще разветвляется дополнительный процесс. Также обратите внимание, что одно отличие состоит в том, что вы не получите никакой ошибки, если попытаетесь прочитать файл типа directory таким образом. Кроме того, хотя он $(< file)является особенным, $(< file; other command)это не так ( zshесли не эмулировать другую оболочку, это все равно расширило бы содержимое file, выполнив неявную $READNULLCMD команду (обычно это пейджер)).


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

1
Да, с ksh , zsh и bash вы можете использовать $(<filename).
— Димитр Радулов

Большое спасибо, это то, что мне было нужно, и это сработало! :-)
— danielmbcn

@Kevin, Dimitre, добавлено сейчас.
— Стефан

4

Добавляя к другим ответам, вы также можете попробовать перенаправление ввода вместо cat

echo $(<my_file.txt)

или

echo `<my_file.txt`

$()и `` выполняют то же самое, они запускают команды внутри своей области видимости и передают вывод в оболочку, как если бы он был задан как ввод пользователем. Единственное различие между ними состоит в том, что $ () может быть рекурсивным и `` не может быть рекурсивным.


2

Простой ответ: вы не можете. echo(будь то встроенная оболочка или обычный двоичный файл) не обрабатывает свой стандартный ввод - это только один способ.


Вопрос в том, почему вы действительно хотите это сделать?
— Петер

2

Как было сказано,

Если вы хотите echoотобразить содержимое файла, вы должны передать его в качестве аргументаecho

Например, вы можете сделать это следующим образом xargs(учитывая, что вам нужно включить интерпретацию обратной косой черты ):

$ cat my_file.txt | xargs echo -e

Или просто то, что вы спросили (без интерпретации последовательностей Escape ):

$ cat my_file.txt | xargs echo

Однако обратите внимание, что при использовании xargs echo(то же самое, что и xargsbtw как echoкоманда по умолчанию) echoбудет выполняться команда из файловой системы, а не встроенная echoкоманда оболочки . Также обратите внимание, что xargsожидается его ввод в очень специфическом формате (где пробелы, новые строки, кавычки, обратные слеши имеют особое значение). catздесь не имеет особого смысла, так как есть только один файл для объединения (так же, как < file.txt xargs echo. Обратите внимание, что Unix-совместимые echos по умолчанию выполняют экранирование с обратной косой чертой и выводят их -eпри этом echo -e.
— Стефан

0

В bash также должно работать следующее:

echo `cat my_file.txt`

Часть в обратных галочках заменяется выводом этой команды, т.е. в этом случае заменяется содержимым файла.


Правда, галочки работают как $( . . . ). Люди, которые используют, $()обычно предпочитают их, потому что вы можете их вкладывать. Этот вопрос старый, но гораздо приятнее отвечать на вопросы, на которые еще нет ответа!
— Закон 29

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

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