Redireccionar el contenido de un archivo al comando "echo"

41

Tengo un archivo llamado my_file.txtcuyo contenido es solo la cadena Hello. ¿Cómo podría redirigir su contenido al comando echo?

Sé que tengo los comandos less, cat, more... pero tengo que hacerlo con echo.

Intenté esto:

$ cat my_file.txt | echo

y también esto:

$ echo < my_file.txt

Pero en ambos casos, solo aparece un espacio en blanco en el stdout, no el contenido de my_file.txt.

¿Cómo podría hacer eso?

danielmbcn
fuente
77
¿Por qué insistes en usar echo?
Kevin
77
@Kevin, presumiblemente eventualmente quiere expandir las secuencias de escape ANSI C ( \n, b...) en el archivo, lo que sería un uso válido de echo(al menos un estándar echo). O presumiblemente quiere entender por qué no funciona de esa manera. En cualquier caso, no hay razón para rechazar la OMI.
Stéphane Chazelas
3
Vine aquí porque tenía curiosidad acerca de por qué no funciona cuando echo <file.txt. Parece una pregunta razonable tener en SE, la respuesta fue muy útil. +1 de mi parte
neuronet

Respuestas:

53

Puedes redirigir todo lo que quieras echopero no hará nada con él. echono lee su entrada estándar. Todo lo que hace es escribir en la salida estándar sus argumentos separados por un carácter de espacio y terminados por un carácter de nueva línea (y con algunas echoimplementaciones con algunas secuencias de escape en ellas expandidas y / o argumentos comenzando con -posiblemente tratados como opciones).

Si desea echomostrar el contenido de un archivo, debe pasar ese contenido como argumento a echo. Algo como:

echo "$(cat my_file.txt)"

Tenga en cuenta que $(...)despoja al carácter de nueva línea de arrastre s de la salida de ese catcomando, y echoañade una vuelta.

También tenga en cuenta que, excepto con zsh, no puede pasar caracteres NUL en los argumentos de un comando, por lo que lo anterior normalmente no funcionará con archivos binarios. yashtambién eliminará los bytes que no forman parte de los caracteres válidos.

Si la razón para querer hacer eso es porque quiere echoampliar el \n, \b, \0351... secuencias de escape en el archivo (como UNIX conformes echoimplementaciones hacen, pero no en todos ), entonces prefiere utilizar printfen su lugar :

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

Al contrario echo, ese es portátil y no tendrá problemas si el contenido del archivo comienza con -.


Como alternativa a $(cat file), con ksh, zshy bash, también se puede hacer:$(<file) . Es un operador especial mediante el cual el shell , en lugar de catleer, lee el contenido del archivo para completar la expansión. Todavía despoja las líneas nuevas y chokes finales en bytes NUL excepto en zsh. En basheso todavía se bifurca un proceso extra. También tenga en cuenta que una diferencia es que no obtendrá ningún error si intenta leer un archivo de tipo directorio de esa manera. Además, si bien $(< file)es especial, $(< file; other command)no lo es (en zsh, cuando no se emula a otro shell, eso aún expandiría el contenido del file, ejecutando el comando implícito $READNULLCMD (generalmente un localizador)).

Stéphane Chazelas
fuente
3
Tanto en bash y zsh puede omitir el caty sólo tienen la cáscara leyó en directo: echo "$(<my_file.txt)".
Kevin
1
Sí, con ksh , zsh y bash puedes usar $(<filename).
Dimitre Radoulov
¡Muchas gracias, eso es lo que necesitaba y funcionó! :-)
danielmbcn
@Kevin, Dimitre, agregó ahora.
Stéphane Chazelas
4

Además de otras respuestas, también puede intentar la redirección de entrada en lugar de cat

echo $(<my_file.txt)

o

echo `<my_file.txt`

$()y `` realizan lo mismo, ejecutan comandos dentro de su alcance y dan la salida al shell como si el usuario la hubiera dado como entrada. La única diferencia entre estos dos es que $ () puede ser recursivo y `` no puede ser recursivo.

GitanoCosmonauta
fuente
2

Respuesta simple: no puedes. echo(ya sea shell incorporado o binario regular) no procesa su entrada estándar, es de una sola manera.

Peterph
fuente
La pregunta es, ¿por qué realmente querrías hacer esto?
Peter
2

Como se dijo

Si desea echomostrar el contenido de un archivo, debe pasar ese contenido como argumento paraecho

Por ejemplo, puede hacerlo así xargs(teniendo en cuenta que necesita habilitar la interpretación de los escapes de barra invertida ):

$ cat my_file.txt | xargs echo -e

O simplemente lo que ha preguntado (sin interpretación de secuencias de escape ):

$ cat my_file.txt | xargs echo
kenichi
fuente
Sin embargo , tenga en cuenta que cuando se usa xargs echo(igual que por xargscierto, echoes el comando predeterminado), se echoejecutará el comando del sistema de archivos, no el echocomando incorporado del shell . También tenga en cuenta que xargsespera su entrada en un formato muy específico (donde los espacios en blanco, las nuevas líneas, las comillas y las barras invertidas tienen un significado especial). catno tiene mucho sentido aquí, ya que solo hay un archivo para concatenar (igual que < file.txt xargs echo. Tenga en cuenta que los que cumplen con Unix echohacen la expansión de escape de barra invertida de forma predeterminada y se -eecho -e
imprimen
0

En bash, también debería funcionar lo siguiente:

echo `cat my_file.txt`

La parte de los backticks se reemplaza por la salida de ese comando, es decir, en este caso se reemplaza por el contenido del archivo.

Motlib
fuente
Es cierto que los backticks funcionan como $( . . . ). Las personas que usan $()generalmente los prefieren porque puedes anidarlos. Sin embargo, esta pregunta es antigua, ¡es mucho más satisfactorio responder preguntas que aún no se han respondido!
Law29
No exactamente. Hay una sutil diferencia. Cuando se utiliza el formulario de retroceso, una barra diagonal inversa conserva su significado literal, excepto cuando va seguido de $, `o \. La primera marca de retroceso no precedida por una barra invertida termina el comando. Cuando se usa el formulario $ (,,,), todos los caracteres entre paréntesis forman el comando.
fpmurphy 01 de
Como no se cita esa sustitución de comando, se le aplicaría el operador split + glob. Por ejemplo, si my_file.txtcontiene *, eso imprimiría la lista de nombres de archivo en el directorio actual.
Stéphane Chazelas