Des programmes comme catlire uniquement à partir de l'entrée standard s'ils n'ont pas d'arguments de nom de fichier.
Barmar
Réponses:
23
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.
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 abcetcat 1.txt ensemble. En être témoin:
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.
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.
Cette réponse peut être améliorée en expliquant comment cela fonctionne et pourquoi la tentative originale du PO ne fonctionne pas.
Bob
OK, j'ai essayé.
Gerard H.Pille
5
Un sous-shell n'est pas expressément requis ici, il serait peut-être préférable d'utiliser une commande de groupe. Voir ma réponse pour plus de détails.
Cette réponse peut être améliorée en expliquant pourquoi la tentative initiale du PO ne fonctionne pas (et donc pourquoi cela est nécessaire à la place).
Bob
1
La <(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.
Rhialto prend en charge Monica le
0
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
Comment la 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).
Charles Duffy
0
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:
Cela va (1) mettre abcen bas de 2.txt; la question le veut tout en haut. (2) modifier le 1.txtfichier; C'est inacceptable.
G-Man dit `` Réintègre Monica '' le
Où est-ce que ça dit? Ringger81 n'a jamais précisé où, dans 2.txt, il voulait que abc apparaisse. Vous supposez des choses que la question ne dit jamais.
Nasir Riley
(1) OK, vous soulevez un point valide sur # 1. Bien que la question mentionne «sortie de l'écho» avant «contenu d'un fichier» dans le texte, puis place l' 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.
G-Man dit `` Réintègre Monica '' le
Je peux comprendre votre point de ne pas modifier le fichier imput. Mon deuxième code obtiendra l'effet souhaité sans le faire.
Nasir Riley
1
Ouvrir un fichier, l'ajouter, le fermer , l'ouvrir à nouveau, l'ajouter à nouveau ... pourquoi faire cela plutôt que de l'ouvrir une seule fois et de conserver la redirection en place pour les deux opérations?
cat
lire uniquement à partir de l'entrée standard s'ils n'ont pas d'arguments de nom de fichier.Réponses:
Cela ne fonctionne pas car le
cat
programme de votre séquence de tuyaux n'a pas été invité à lire laecho
sortie du programme à partir de l'entrée standard.Vous pouvez utiliser
-
comme pseudo-nom de fichier pour indiquer une entrée standard danscat
. Depuisman cat
une installation msys2:Alors essayez
au lieu.
la source
Comme indiqué par d'autres, votre commande d'origine échoue car ne
cat 1.txt
tient 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 redirigerecho abc
etcat 1.txt
ensemble. En être témoin:Extrait pertinent du manuel (
man bash
):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.
la source
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.
la source
bash(1)
, elle décrit le comportement que chaque shell compatible POSIX doit prendre en charge.Votre commande
cat 1.txt
ne fait rien avec la sortie deecho "abc"
.Au lieu de cela:
(echo "abc"; cat 1.txt) > 2.txt
écrira la sortie des deux commandes dans 2.txt.la source
Dans n'importe quel shell POSIX, vous pouvez utiliser la substitution de commandes à utiliser
cat file
comme entrée pourecho
:Dans Bash, vous pouvez utiliser la substitution de processus et utiliser l'écho comme un autre "fichier" pour
cat
, comme dans: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)
la source
<(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.
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:
Votre fonction s'appelle ecat, ce qui est mémorable.
Vous pouvez maintenant invoquer
Pour ajouter, fournissez simplement une destination de sortie différente à stdout:
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.
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
la source
"$1"
et"$2"
. Dans ce contexte, les accolades ne servent à rien. Voir${name}
ne signifie pas ce que vous pensez que cela fait… .noclobber
suggestion 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:
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:
la source
abc
en bas de2.txt
; la question le veut tout en haut. (2) modifier le1.txt
fichier; C'est inacceptable.echo
avant avantcat
dans 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.txt
est un fichier d'entrée. La question ne dit rien sur la modification1.txt
. Le fait que les fichiers d'entrée ne doivent pas être modifiés va de soi.