Réponses:
Cela ne fonctionne pas car le catprogramme de votre séquence de tuyaux n'a pas été invité à lire la echosortie du programme à partir de l'entrée standard.
Vous pouvez utiliser -comme pseudo-nom de fichier pour indiquer une entrée standard dans cat. Depuis man catune installation msys2:
EXAMPLES
cat f - g
Output f's contents, then standard input, then g's contents.
Alors essayez
echo "abc" | cat - 1.txt > 2.txt
au lieu.
Comme indiqué par d'autres, votre commande d'origine échoue car ne cat 1.txttient pas compte de son entrée standard. Soit indiquer qu'il doit être son premier argument ( cat - 1.txt), soit utiliser la redirection de bloc pour rediriger echo abc et cat 1.txt ensemble. En être témoin:
{ echo abc; cat 1.txt; } > 2.txt
Extrait pertinent du manuel ( man bash):
Commandes
composées Une commande composée est l'une des suivantes. Dans la plupart des cas, une liste dans la description d'une commande peut être séparée du reste de la commande par un ou plusieurs sauts de ligne et peut être suivie d'un saut de ligne à la place d'un point-virgule.
(liste)La liste est exécutée dans un environnement de sous-shell (voir ENVIRONNEMENT D'EXÉCUTION DE COMMANDE ci-dessous). Les affectations de variables et les commandes intégrées qui affectent l'environnement du shell ne restent pas en vigueur une fois la commande terminée. Le statut de retour est le statut de sortie de la liste.
{liste;}La liste est simplement exécutée dans l'environnement shell actuel. la liste doit se terminer par une nouvelle ligne ou un point-virgule. C'est ce qu'on appelle une commande de groupe . Le statut de retour est le statut de sortie de la liste . Notez que, contrairement aux métacaractères
(et),{et}sont des mots réservés et doivent se produire lorsqu'un mot réservé est autorisé à être reconnu. Comme ils ne provoquent pas de rupture de mot, ils doivent être séparés de la liste par des espaces ou un autre métacaractère shell.
La première option (environnement sous-shell) a un tas d'effets secondaires, la plupart sinon tous sans rapport avec votre scénario; cependant, si la redirection d'un groupe de commandes est tout ce dont vous avez besoin, l'option # 2 ici (commande de groupe) est préférable.
( echo "abc"; cat 1.txt ) > 2.txt
Vous avez canalisé la sortie d'écho vers cat, mais cat n'avait aucune utilité pour l'entrée et l'ignoriez. Maintenant, les commandes s'exécutent les unes après les autres, et leur sortie est groupée (les parenthèses) et dirigée dans 2.txt.
bash(1), elle décrit le comportement que chaque shell compatible POSIX doit prendre en charge.
Dans n'importe quel shell POSIX, vous pouvez utiliser la substitution de commandes à utiliser cat filecomme entrée pour echo:
echo $(cat file1.txt) "This Too"
Dans Bash, vous pouvez utiliser la substitution de processus et utiliser l'écho comme un autre "fichier" pour cat, comme dans:
cat file1.txt <(echo This Too)
puis canalisez ou redirigez la sortie comme bon vous semble.
Comme toutes les autres réponses, cat ignore stdin s'il a un fichier à consulter. (J'aime aussi les réponses de Daniel & mvw, +1 pour eux)
<(command)construction est une extension bash. Ce n'est pas POSIX, vous ne pouvez donc pas vous y fier dans des scripts censés être exécutés avec /bin/sh.
Juste une supposition, mais il semble que vous ayez un processus reproductible, ce qui est un bon candidat pour un alias ou une fonction. Les alias sont généralement des raccourcis pour appeler des commandes bash, telles que l'abréviation, sur un seul flux d'entrée comme argument / s.
alias hg="history | grep"
Cependant, dans ce cas, une fonction serait plus lisible, car vous combinez plusieurs flux d'entrée discrets (2) ainsi que plusieurs commandes bash. Vous avez deux arguments, le premier étant une chaîne et l'autre un chemin de fichier. En fin de compte, vous souhaitez que le résultat soit écrit dans le flux de sortie standard.
À partir d'une invite CLI, tapez ceci:
# ecat()
{
echo ${1}
cat ${2}
}
Votre fonction s'appelle ecat, ce qui est mémorable.
Vous pouvez maintenant invoquer
ecat "abc" 1.txt
Pour ajouter, fournissez simplement une destination de sortie différente à stdout:
ecat "abc" 1.txt >> 2.txt
L'opérateur de redirection d'ajout '>>' ajoutera la sortie à la fin du fichier spécifié.
Si vous l'aimez, ajoutez-le à votre fichier ~ / .bashrc pour le réutiliser.
declare -f ecat >> ~/.bashrc
Cela signifie également que vous pouvez décorer, etc., au sein de votre définition de fonction.
Aussi une bonne idée de protéger les fichiers contre l'écrasement en les ajoutant à votre ~ / .bashrc
set noclobber
"$1"et "$2". Dans ce contexte, les accolades ne servent à rien. Voir ${name}ne signifie pas ce que vous pensez que cela fait… .
noclobbersuggestion répond-elle à la question posée? (Je ne suis pas non plus convaincu que ce soit un bon conseil - la modification du comportement global a tendance à casser les scripts / conseils / pratiques construits avec les valeurs par défaut à l'esprit).
Le code suivant fonctionnera également:
echo abc >> 1.txt && cat 1.txt > 2.txt
La sortie de echo abc sera ajoutée à 1.txt avec >> Après cela, le && lui dira d'exécuter le prochain ensemble de commandes qui cat 1.txt et le sortira ensuite à 2.txt . Fondamentalement, il ajoute la sortie de la première commande dans 1.txt, puis envoie la sortie de 1.txt dans 2.txt.
Si vous souhaitez que l'abc apparaisse en premier, vous pouvez utiliser le code suivant:
echo abc >> 2.txt && cat 1.txt >> 2.txt
abcen bas de 2.txt; la question le veut tout en haut. (2) modifier le 1.txtfichier; C'est inacceptable.
echoavant avant catdans la commande exemple, je suppose qu'elle ne dit jamais exactement, explicitement , qu'elle veut la sortie de l'écho avant la contenu du fichier d'entrée. Il semble que la plupart des gens l'ont interprété de cette façon. (2) 1.txtest un fichier d'entrée. La question ne dit rien sur la modification 1.txt. Le fait que les fichiers d'entrée ne doivent pas être modifiés va de soi.
catlire uniquement à partir de l'entrée standard s'ils n'ont pas d'arguments de nom de fichier.