Existe-t-il une commande Unix pour ajouter des chaînes de caractères dans un fichier texte?
Quelque chose comme:
prepend "to be prepended" text.txt
unix
command-line
utilities
prepend
Un deux trois
la source
la source
<<(echo "to be prepended") < text.txt | sponge text.txt
Réponses:
-i
écrit le changement en place et effectue une sauvegarde si une extension est donnée. (Dans ce cas,.old
)1s;^;to be prepended;
remplace le début de la première ligne par la chaîne de remplacement donnée, en utilisant;
comme délimiteur de commande.la source
\n
après le préfixe; en fonction de leurs besoins. Solution soignée.inFile
Les répertoires inclus dans son chemin peuvent-ils être inclus?\n
. J'aurais dû lire les commentaires en premier. Zut.'1s;^;my-prepended-line\;\n;'
la source
git config --get-regex $arg | sed -r 's/\t{3}/\\n/g';
et cela gâche car il convertit le\t
et\n
.echo "to be prepended"$'\n'"$(cat text.txt)"
Substitution de processus
Je suis surpris que personne n'ait mentionné cela.
ce qui est sans doute plus naturel que la réponse acceptée (imprimer quelque chose et le faire passer dans une commande de substitution est contre-intuitif lexicographiquement).
... et détournant ce que Ryan a dit ci-dessus,
sponge
vous n'avez pas besoin d'un fichier temporaire:EDIT: On dirait que cela ne fonctionne pas dans Bourne Shell
/bin/sh
Here String (zsh uniquement)
En utilisant une chaîne ici -
<<<
, vous pouvez faire:la source
<<(echo "to be prepended") < text.txt
et vos<<< "to be prepended" < text.txt
constructions ne fonctionnent pas en bash; ils nécessitent zsh.Voici une possibilité:
vous ne pourrez probablement pas contourner facilement un fichier intermédiaire.
Alternatives (peuvent être lourdes avec l'échappement du shell):
la source
cat <(echo "to be prepended") text.txt > newfile.txt
. À bien y penser, je ne suis pas sûr que le mien soit lié, alors je poste une réponse séparée.Cela fonctionnera pour former la sortie. Le - signifie une entrée standard, qui est fournie via le tuyau de l'écho.
Pour réécrire le fichier, un fichier temporaire est requis car il ne peut pas être redirigé vers le fichier d'entrée.
la source
text.txt
comme demandé, mais l'affiche sur stdout. La sortie pourrait être canalisée dans un fichier différent si cela fonctionne pour l'OPPréfère la réponse d'Adam
Nous pouvons faciliter l'utilisation de l' éponge . Maintenant, nous n'avons pas besoin de créer un fichier temporaire et de le renommer en
la source
S'il est acceptable de remplacer le fichier d'entrée:
Remarque:
Cela peut avoir des effets secondaires inattendus, notamment le remplacement potentiel d'un lien symbolique par un fichier normal, se retrouver avec des autorisations différentes sur le fichier et modifier la date de création (naissance) du fichier.
sed -i
, comme dans la réponse du prince John Wesley , tente au moins de restaurer les autorisations d'origine, mais les autres limitations s'appliquent également.Voici une alternative simple qui utilise un fichier temporaire (cela évite de lire le fichier d'entrée entier en mémoire comme le fait la solution de Shime ):
L'utilisation d'une commande de groupe (
{ ...; ...; }
) est légèrement plus efficace que l'utilisation d'un sous - shell ((...; ...)
), comme dans la solution de 0xC0000022L .Les avantages sont:
Il est facile de contrôler si le nouveau texte doit être directement ajouté à la première ligne ou s'il doit être inséré en tant que nouvelle (s) ligne (s) (ajoutez simplement
\n
à l'printf
argument).Contrairement à la
sed
solution, cela fonctionne si le fichier d'entrée est vide (0
octets).La
sed
solution peut être simplifiée si l'intention est d'ajouter au début une ou plusieurs lignes entières au contenu existant (en supposant que le fichier d'entrée n'est pas vide):sed
Lai
fonction de insère des lignes entières:Avec GNU
sed
:Une variante portable qui fonctionne également avec macOS / BSD
sed
:Notez que le saut de ligne littéral après le
\
est obligatoire.Si le fichier d'entrée doit être édité sur place (en conservant son inode avec tous ses attributs):
Utilisation du vénérable
ed
utilitaire POSIX :Remarque:
ed
lit invariablement le fichier d'entrée dans son ensemble en mémoire en premier.Pour ajouter directement à la première ligne (comme avec
sed
, cela ne fonctionnera pas si le fichier d'entrée est complètement vide (0
octets)):-s
ed
messages d'état supprimés .ed
sous forme de document here-document (<<EOF\n...\nEOF
) sur plusieurs lignes , c'est-à-dire via stdin ; par défaut, l'expansion des chaînes est effectuée dans ces documents (les variables shell sont interpolées); citez le délimiteur d'ouverture pour supprimer cela (par exemple,<<'EOF'
).1
fait de la 1ère ligne la ligne courantes
effectue une substitution de chaîne basée sur une expression régulière sur la ligne courante, comme danssed
; vous pouvez inclure des sauts de ligne littéraux dans le texte de substitution, mais ils doivent être\
échappés.w
réécrit le résultat dans le fichier d'entrée (pour le test, remplacezw
par,p
pour imprimer uniquement le résultat, sans modifier le fichier d'entrée).Pour ajouter une ou plusieurs lignes entières au début :
Comme avec
sed
, lai
fonction ajoute invariablement une nouvelle ligne à la fin du texte à insérer.0 i
fait0
(le début du fichier) la ligne courante et démarre le mode insertion (i
); notez que les numéros de ligne sont1
basés sur une autre base..
sur sa propre ligne.la source
Probablement rien de intégré, mais vous pouvez écrire le vôtre assez facilement, comme ceci:
Quelque chose comme ça au moins ...
la source
$$
est cependant insuffisante pour le code de production (attaque de lien symbolique google); mais c'est certainement mieux qu'un nom de fichier statique.mktemp
Dans certaines circonstances, le texte préfixé peut être disponible uniquement à partir de stdin. Ensuite, cette combinaison fonctionnera.
Si vous souhaitez omettre la
tee
sortie, ajoutez> /dev/null
.la source
tee
ne clobe pastext.txt
avantcat
de le lire? Je ne pense pas - ce qui rendrait cette solution dangereuse pour la santé du dossier.lenA=1000000; yes a | head -c $lenA > a.txt; lenB=10000; b=$(yes b | head -c $lenB); echo "$b" | cat - a.txt | tee a.txt > /dev/null
. SilenA
vaut 1000000 (fichier de 1 Mo) etlenB
10000 (texte de 10 Ko en préfixe), alors le fichier "a.txt" est écrasé par 20 Ko de lettres "b". C'est totalement cassé. Maintenant, si vous utilisez 1Mb a.txt et 1Mb de texte à ajouter,tee
entre dans une boucle générant un fichier 7Gb +, j'ai dû arrêter la commande. Il est donc évident que le résultat est imprévisible pour les grandes tailles. Je n'ai aucune information si cela devrait fonctionner sur de petites tailles.Solution:
Notez que cela est sûr sur tous les types d'entrées, car il n'y a pas d'extensions. Par exemple, si vous souhaitez ajouter un préfixe
!@#$%^&*()ugly text\n\t\n
, cela fonctionnera simplement:La dernière partie à considérer est la suppression des espaces à la fin du fichier lors de la substitution de commande
"$(cat file.txt)"
. Toutes les solutions de contournement pour cela sont relativement complexes. Si vous souhaitez conserver les nouvelles lignes à la fin de file.txt, voir ceci: https://stackoverflow.com/a/22607352/1091436la source
file.txt
est plus grand que ce qui peut être inséré dans la liste d'argumentsprintf
.Une autre façon d'utiliser
sed
:Si la ligne à ajouter est multiligne:
la source
sed -i '1ito be prepended' inFile
- ou est-ce uniquement autorisé pour GNU sed?sed
, lai
commande est suivie d'une barre oblique inverse et d'une nouvelle ligne, et chaque ligne d'entrée sauf la dernière se termine également par une barre oblique inverse. GNUsed
autorise les raccourcis dans le sens que vous demandez, mais ce n'est que GNUsed
qui le fait. 'Comme testé dans Bash (dans Ubuntu), si vous démarrez avec un fichier de test via;
echo "Original Line" > test_file.txt
vous pouvez exécuter;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
ou, si la version de bash est trop ancienne pour $ (), vous pouvez utiliser des backticks;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
et recevez le contenu suivant de "test_file.txt";
Pas de fichier intermédiaire, juste bash / echo.
la source
Une autre solution assez simple est:
la source
cat
expansion des paramètres entre guillemets doubles est une très bonne raison pour un vote défavorable . Ce code divise le contenu du fichier en mots et passe chacun de ces mots comme argument distinct àecho
. Vous perdez les limites des arguments d'origine, vous perdez les nouvelles lignes / tabulations / etc., et les chaînes comme\t
et\n
dans le texte d'origine sont remplacées par des tabulations et des nouvelles lignes au lieu d'être conservées telles quelles.Si vous aimez vi / vim, c'est peut-être plus votre style.
la source
la source
Je recommanderais de définir une fonction, puis de l'importer et de l'utiliser si nécessaire.
Ensuite, utilisez-le comme ceci:
Le contenu de votre fichier sera alors:
Je suis sur le point d'utiliser cette approche pour implémenter un programme de mise à jour du journal des modifications.
la source