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 abcecat 1.txt juntos. A saber:
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).
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.
Esta resposta pode ser melhorada, explicando como a alternativa sugerida funciona.
Bob
1
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)
Essa resposta pode ser melhorada, explicando por que a tentativa original do OP não funciona (e, portanto, por que isso é necessário).
Bob
1
A <(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.
Rhialto apoia Monica
0
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
Como a 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).
Charles Duffy
0
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:
Isso irá (1) colocar abcna parte inferior de 2.txt; a pergunta quer no topo. (2) modificar o 1.txtarquivo; isso é inaceitável.
G-Man diz 'Reinstate Monica'
Onde isso diz isso? Ringger81 nunca especificou onde, em 2.txt, ele queria que o abc aparecesse. Você está assumindo coisas que a pergunta nunca afirma.
Nasir Riley
(1) OK, você eleva um ponto válido no # 1. Enquanto a pergunta menciona "saída do eco" antes do "conteúdo de um arquivo" no texto e, em seguida, coloca o comando 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.
G-Man diz 'Reinstate Monica'
Entendo seu ponto de vista sobre não modificar o arquivo de imputação. Meu segundo código alcançará o efeito desejado sem fazer isso.
Nasir Riley
1
Abrindo um arquivo, anexando-o, fechando-o , abrindo-o novamente, anexando-o novamente ... por que fazer isso em vez de apenas abri-lo uma vez e manter o redirecionamento no lugar para as duas operações?
cat
apenas leem da entrada padrão se não tiverem nenhum argumento de nome de arquivo.Respostas:
Não funciona porque o
cat
programa na sequência de tubulação não foi instruído a ler aecho
saída do programa a partir da entrada padrão.Você pode usar
-
como um nome de pseudo arquivo para indicar entrada padrão paracat
. Emman cat
uma instalação do msys2:Então tente
em vez de.
fonte
Conforme observado por outras pessoas, seu comando original falha porque
cat 1.txt
desconsidera sua entrada padrão. Indique que esse deve ser o primeiro argumento (cat - 1.txt
) ou use o redirecionamento de bloco para redirecionarecho abc
ecat 1.txt
juntos. A saber:Trecho relevante do manual (
man bash
):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).
fonte
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.
fonte
bash(1)
, ela descreve o comportamento que todo shell compatível com POSIX deve suportar.Seu comando
cat 1.txt
não faz nada com a saída deecho "abc"
.Em vez disso:
(echo "abc"; cat 1.txt) > 2.txt
gravará a saída dos dois comandos no 2.txt.fonte
Em qualquer shell POSIX, você pode usar a substituição de comando para usar
cat file
como entrada paraecho
:No Bash, você pode usar a substituição do processo e usar o eco como outro "arquivo" para
cat
, como em: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)
fonte
<(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).
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:
Sua função é denominada ecat, que é memorável.
Agora você pode chamar como
Para acrescentar, basta fornecer um destino de saída diferente ao stdout:
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.
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
fonte
"$1"
e"$2"
. Nesse contexto, o aparelho não faz nenhum bem. Ver${name}
não significa o que você pensa que faz .noclobber
sugestã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á:
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:
fonte
abc
na parte inferior de2.txt
; a pergunta quer no topo. (2) modificar o1.txt
arquivo; isso é inaceitável.echo
antes docat
no 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ção1.txt
. O fato de que os arquivos de entrada não devem ser modificados é desnecessário.