Redirecionando o conteúdo de um arquivo para o comando "eco"

41

Eu tenho um arquivo chamado my_file.txtcujo conteúdo é apenas a string Hello. Como eu poderia redirecionar seu conteúdo para o comando echo?

Eu sei que tenho os comandos less, cat, more... mas eu preciso fazê-lo com echo.

Eu tentei isso:

$ cat my_file.txt | echo

e também isso:

$ echo < my_file.txt

Mas nos dois casos, ele aparece apenas em branco no stdout, não no conteúdo do meu_arquivo.txt.

Como eu pude fazer isso?

danielmbcn
fonte
7
Por que você insiste em usar echo?
Kevin
7
@ Kevin, presumivelmente, eventualmente, ele deseja expandir as seqüências de escape ANSI C ( \n, b...) no arquivo, o que seria um uso válido de echo(pelo menos um padrão echo). Ou, presumivelmente, ele quer entender por que não funciona dessa maneira. Em qualquer caso, não há razão para fazer voto negativo na IMO.
Stéphane Chazelas
3
Eu vim aqui porque estava curioso sobre por que não funciona quando faço eco <arquivo.txt. Parece uma pergunta razoável para se ter na SE, a resposta foi muito útil. +1 de mim.
Neuronet

Respostas:

53

Você pode redirecionar tudo o que quiser, echomas não fará nada com isso. echonão lê sua entrada padrão. Tudo o que faz é gravar na saída padrão seus argumentos separados por um caractere de espaço e finalizados por um caractere de nova linha (e com algumas echoimplementações com algumas seqüências de escape nelas expandidas e / ou argumentos iniciados com -possivelmente tratados como opções).

Se você deseja echoexibir o conteúdo de um arquivo, deve passar esse conteúdo como argumento echo. Algo como:

echo "$(cat my_file.txt)"

Note-se que $(...)retira o caractere de nova linha de fuga s da saída desse catcomando, e echoacrescenta uma volta.

Observe também que, exceto com zsh, você não pode passar caracteres NUL nos argumentos de um comando, portanto, acima, normalmente, não funcionará com arquivos binários. yashtambém removerá bytes que não fazem parte de caracteres válidos.

Se a razão para querer fazer isso é porque você quer echopara expandir o \n, \b, \0351... sequências de escape no arquivo (como conformant UNIX echoimplementações fazer, mas não todos ), então você preferir usar printfvez :

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

Ao contrário echo, esse é portátil e não terá problemas se o conteúdo do arquivo começar -.


Como uma alternativa para $(cat file), com ksh, zshe bash, pode-se também fazer:$(<file) . Esse é um operador especial pelo qual o shell, em vez de catler o conteúdo do arquivo, compõe a expansão. Ele ainda retira as novas linhas finais e engasga com bytes NUL, exceto em zsh. Em bash, isso ainda bifurca um processo extra. Observe também que uma diferença é que você não receberá nenhum erro se tentar ler um arquivo do tipo diretório dessa maneira. Além disso, embora $(< file)seja especial, $(< file; other command)não é (em zsh, quando não emula outro shell, que ainda expandiria o conteúdo do file, executando o comando implícito $READNULLCMD (normalmente um pager)).

Stéphane Chazelas
fonte
3
Em ambos bash e zsh você pode pular o cate só tem o shell lê-lo em diretamente: echo "$(<my_file.txt)".
Kevin
11
Sim, com ksh , zsh e bash você pode usar $(<filename).
Dimitre Radoulov
Muito obrigado, era disso que eu precisava e funcionou! :-)
danielmbcn
@ Kevin, Dimitre, adicionado agora.
Stéphane Chazelas
4

Além de outras respostas, você também pode tentar o redirecionamento de entrada em vez de cat

echo $(<my_file.txt)

ou

echo `<my_file.txt`

$()e `` executam a mesma coisa, eles executam comandos dentro de seu escopo e entregam a saída para o shell como se fosse dada como entrada pelo usuário. A única diferença entre esses dois é que $ () pode ser recursivo e `` não pode ser recursivo.

CiganoCosmonauta
fonte
2

Resposta simples: você não pode. echo(seja shell interno ou binário regular) não processa sua entrada padrão - é apenas uma maneira.

peterph
fonte
A pergunta é: por que você realmente deseja fazer isso?
Peterph
2

Como foi dito,

Se você deseja echoexibir o conteúdo de um arquivo, é necessário passar esse conteúdo como argumento paraecho

Por exemplo, você pode fazer assim com xargs(considerando que você precisa habilitar a interpretação de escapes de barra invertida ):

$ cat my_file.txt | xargs echo -e

Ou simplesmente o que você pediu (sem interpretação das seqüências de escape ):

$ cat my_file.txt | xargs echo
kenichi
fonte
Observe, no entanto, que ao usar xargs echo(o mesmo que xargsbtw e echoo comando padrão), é o echocomando do sistema de arquivos que será executado, não o echocomando interno do shell . Observe também que xargsespera sua entrada em um formato muito específico (onde espaços em branco, novas linhas, aspas, barras invertidas têm um significado especial). catnão faz muito sentido aqui como há apenas um arquivo para concatenar (o mesmo que < file.txt xargs echoNote que compatíveis com Unix. echos fazer expansão de escape barra invertida por padrão e saída -eem cima echo -e.
Stéphane Chazelas
0

No bash, também deve funcionar o seguinte:

echo `cat my_file.txt`

A parte nos backticks é substituída pela saída desse comando, ou seja, neste caso, substituída pelo conteúdo do arquivo.

Motlib
fonte
É verdade que os backticks funcionam como $( . . . ). As pessoas que usam $()geralmente preferem, porque você pode aninhar. Esta questão é antiga, porém, é muito mais gratificante responder a perguntas que ainda não foram respondidas!
precisa
Nem tanto. Há uma diferença sutil. Quando o formulário de rechamada é usado, uma barra invertida mantém seu significado literal, exceto quando seguido por $, `ou \. O primeiro back-tick não precedido por uma barra invertida finaliza o comando. Ao usar o formulário $ (,,,), todos os caracteres entre parênteses formam o comando.
Fpmurphy 01/07/19
Como essa substituição de comando não é citada, o operador split + glob seria aplicado a ele. Por exemplo, se my_file.txtcontém *, isso imprimiria a lista de nomes de arquivos no diretório atual.
Stéphane Chazelas