Comando e eco do gato

10

Gostaria de concatenar a saída do eco com o conteúdo de um arquivo. Eu tentei o seguinte comando:

echo "abc" | cat 1.txt > 2.txt

mas o arquivo 2.txt contém apenas o conteúdo de 1.txt . Por que isso não funciona?

    
por Ringger81 13.01.2018 / 11:27

7 respostas

20

Ele não funciona porque o programa cat em sua seqüência de pipe não foi instruído a ler a saída do programa echo da entrada padrão.

Você pode usar - como um nome de arquivo pseudo para indicar a entrada padrão para cat . De man cat em uma instalação do msys2:

EXAMPLES
       cat f - g
              Output f's contents, then standard input, then g's contents.

Então, tente

echo "abc" | cat - 1.txt > 2.txt

em vez disso.

    
por 13.01.2018 / 11:54
16

Como observado por outros, seu comando original falha porque cat 1.txt desconsidera sua entrada padrão. Indica que deve ser seu primeiro argumento ( cat - 1.txt ) ou usa bloqueio de redirecionamento para redirecionar echo abc e cat 1.txt juntos. A saber:

{ echo abc; cat 1.txt; } > 2.txt 

Trecho relevante do manual ( man bash ):

Compound Commands
A compound command is one of the following.  In most cases a list in a command's description may be separated from the rest of the command by one or more newlines, and may be followed by a newline in place of a semicolon.

(list)

    list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes.  The return status is the exit status of list.

{list; }

    list is simply executed in the current shell environment.  list must be terminated with a newline or semicolon.  This is known as a group command.  The return status is the exit status of list.  Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized.  Since they do not cause a word break, they must be separated from list by whitespace or another shell metacharacter.

A primeira opção (ambiente de subcamadas) tem vários efeitos colaterais, a maioria, se não todos, irrelevantes para o seu cenário; No entanto, se o redirecionamento de um conjunto de saídas de comandos for tudo o que você precisa, então a Opção nº 2 aqui (comando de grupo) é a preferida.

    
por 13.01.2018 / 16:22
5
( echo "abc"; cat 1.txt ) > 2.txt

Você canalizou a saída de eco para cat, mas o cat não teve uso para entrada e ignorou. Agora os comandos são executados um após o outro e sua saída é agrupada (os parênteses) e direcionada para 2.txt.

    
por 13.01.2018 / 11:42
2

Seu comando cat 1.txt não faz nada com a saída de echo "abc" .

Em vez disso: %código% irá escrever a saída de ambos os comandos em 2.txt.

    
por 13.01.2018 / 11:44
1

Em qualquer shell POSIX, você poderia usar a substituição de comando para usar cat file como entrada para echo :

echo $(cat file1.txt) "This Too"

No Bash você pode usar a substituição de processos e usar o echo como outro "arquivo" para cat , como em:

cat file1.txt <(echo This Too)

e, em seguida, canalize ou redirecione a saída como achar melhor.

Como todas as outras respostas, cat ignora stdin se tiver um arquivo para ver. (Eu também gosto das respostas de Daniel & mvw, +1 para elas)

    
por 13.01.2018 / 11:39
0

Apenas um palpite, mas parece que você tem um processo repetível, que é um bom candidato para um alias ou uma função. Os aliases são geralmente atalhos para invocar comandos bash, como abreviação, em um único fluxo de entrada como seu argumento / s.

alias hg="history | grep"

No entanto, nesse caso, uma função seria mais legível, já que você está combinando vários fluxos de entrada discretos (2), bem como vários comandos bash. Você tem dois argumentos, o primeiro sendo uma string e o outro um caminho de arquivo. No final, você quer que o resultado seja gravado no fluxo de saída stdout.

Em um prompt da CLI, digite:

# ecat()        
{
echo ${1}
cat ${2}
}

Sua função é chamada ecat, que é memorável.

Agora você pode invocar como

ecat "abc" 1.txt

Para acrescentar, basta fornecer um destino de saída diferente para stdout:

ecat "abc" 1.txt >> 2.txt

O operador de redirecionamento append '> >' irá adicionar a saída ao final do arquivo especificado.

Se você gostar, acrescente ao seu arquivo ~ / .bashrc para reutilização.

declare -f ecat >> ~/.bashrc

Isso também significa que você pode decorar, etc., dentro de sua definição de função.

Também é uma boa ideia proteger os arquivos contra serem sobrescritos adicionando isso ao seu ~ / .bashrc

set noclobber
    
por 13.01.2018 / 16:59
0

O código a seguir também funciona:

echo abc >> 1.txt && cat 1.txt > 2.txt

A saída de echo abc será anexada a 1.txt com > > Depois disso, o & &; dirá a ele para executar o próximo conjunto de comandos que cat 1.txt e, em seguida, enviá-lo para 2.txt . Basicamente, ele acrescenta a saída do primeiro comando em 1.txt e, em seguida, envia a saída de 1.txt para 2.txt.

Se você deseja que o abc seja exibido primeiro, use o seguinte código:

echo abc >> 2.txt && cat 1.txt >> 2.txt
    
por 13.01.2018 / 14:57

Tags