Respostas:
Não funciona porque o catprograma na sequência de tubulação não foi instruído a ler a echosaída do programa a partir da entrada padrão.
Você pode usar -como um nome de pseudo arquivo para indicar entrada padrão para cat. Em man catuma 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 de.
Conforme observado por outras pessoas, seu comando original falha porque cat 1.txtdesconsidera sua entrada padrão. Indique que esse deve ser o primeiro argumento ( cat - 1.txt) ou use o redirecionamento de bloco para redirecionar echo abc e cat 1.txt juntos. A saber:
{ echo abc; cat 1.txt; } > 2.txt
Trecho relevante do manual ( man bash):
Comandos
compostos Um comando composto é um dos seguintes. Na maioria dos casos, uma lista na descrição de um comando pode ser separada do restante do comando por uma ou mais novas linhas e pode ser seguida por uma nova linha no lugar de um ponto e vírgula.
(Lista)A lista é executada em um ambiente subshell (consulte AMBIENTE DE EXECUÇÃO DE COMANDO abaixo). As atribuições variáveis e os comandos internos que afetam o ambiente do shell não permanecem em vigor após a conclusão do comando. O status de retorno é o status de saída da lista.
{Lista;}A lista é simplesmente executada no ambiente atual do shell. A lista deve ser finalizada com uma nova linha ou ponto e vírgula. Isso é conhecido como um comando de grupo . O status de retorno é o status de saída da lista . Observe que, diferentemente dos metacaracteres
(e),{e}são palavras reservadas, devem ocorrer onde uma palavra reservada pode ser reconhecida. Como eles não causam uma quebra de palavra, eles devem ser separados da lista por espaços em branco ou outro metacaractere do shell.
A primeira opção (ambiente subshell) tem vários efeitos colaterais, a maioria, se não todos, são irrelevantes para o seu cenário; no entanto, se você precisar apenas redirecionar a saída de vários comandos, é preferível a opção 2 aqui (comando de grupo).
( echo "abc"; cat 1.txt ) > 2.txt
Você canalizou a saída de eco para cat, mas cat não tinha utilidade para entrada e a ignorou. Agora, os comandos são executados um após o outro e sua saída é agrupada (parênteses) e direcionada para 2.txt.
bash(1), ela descreve o comportamento que todo shell compatível com POSIX deve suportar.
Em qualquer shell POSIX, você pode usar a substituição de comando para usar cat filecomo entrada para echo:
echo $(cat file1.txt) "This Too"
No Bash, você pode usar a substituição do processo e usar o eco como outro "arquivo" para cat, como em:
cat file1.txt <(echo This Too)
e depois canalize ou redirecione a saída como achar melhor.
Como todas as outras respostas dizem, cat ignora stdin se tiver um arquivo para analisar. (Eu também gosto das respostas de Daniel & mvw, +1 para elas)
<(command)construção é uma extensão do bash. Não é POSIX, portanto você não pode confiar nele em scripts que deveriam ser executados /bin/sh.
Apenas um palpite, mas parece que você tem um processo repetível, que é um bom candidato para um alias ou uma função. Aliases geralmente são atalhos para chamar comandos bash, como abreviação, em um único fluxo de entrada como argumento (s).
alias hg="history | grep"
Entretanto, nesse caso, uma função seria mais legível, pois você está combinando vários fluxos de entrada discretos (2) e vários comandos bash. Você tem dois argumentos, o primeiro sendo uma sequência e o outro um caminho de arquivo. No final, você deseja que o resultado seja gravado no fluxo de saída stdout.
Em um prompt da CLI, digite este:
# ecat()
{
echo ${1}
cat ${2}
}
Sua função é denominada ecat, que é memorável.
Agora você pode chamar como
ecat "abc" 1.txt
Para acrescentar, basta fornecer um destino de saída diferente ao stdout:
ecat "abc" 1.txt >> 2.txt
O operador de redirecionamento de acréscimo '>>' adicionará a saída ao final do arquivo especificado.
Se você gosta, anexe seu arquivo ~ / .bashrc para reutilização.
declare -f ecat >> ~/.bashrc
Isso também significa que você pode decorar, etc., dentro da sua definição de função.
Também é uma boa idéia evitar que os arquivos sejam substituídos adicionando-os ao seu ~ / .bashrc
set noclobber
"$1"e "$2". Nesse contexto, o aparelho não faz nenhum bem. Ver ${name}não significa o que você pensa que faz .
noclobbersugestão responde à pergunta em questão? (Também não estou convencido de que seja um bom conselho - modificar o comportamento global tende a quebrar scripts / conselhos / práticas construídas com os padrões em mente).
O código a seguir também funcionará:
echo abc >> 1.txt && cat 1.txt > 2.txt
A saída do echo abc será anexado ao 1.txt com >> Depois que o && dir-lo para executar o próximo conjunto de comandos que irá 1.txt gato e, em seguida, saída para 2.txt . Basicamente, ele anexa a saída do primeiro comando em 1.txt e envia a saída de 1.txt para 2.txt.
Se você deseja que o abc apareça primeiro, use o seguinte código:
echo abc >> 2.txt && cat 1.txt >> 2.txt
abcna parte inferior de 2.txt; a pergunta quer no topo. (2) modificar o 1.txtarquivo; isso é inaceitável.
echoantes do catno exemplo, suponho que nunca exatamente, explicitamente , diga que deseja a saída do eco antes do conteúdo do arquivo de entrada. Parece que a maioria das pessoas interpretou dessa maneira. (2) 1.txté um arquivo de entrada. A questão não diz nada sobre modificação 1.txt. O fato de que os arquivos de entrada não devem ser modificados é desnecessário.
catapenas leem da entrada padrão se não tiverem nenhum argumento de nome de arquivo.