395 votes

Comment ajouter du texte au début d'un fichier dans Bash ?

Bonjour, je veux ajouter du texte à un fichier. Par exemple, je veux ajouter des tâches au début d'un fichier todo.txt. J'ai connaissance de echo 'task goes here' >> todo.txt mais cela ajoute la ligne à la fin du fichier (pas ce que je veux).

2 votes

Il n'y a pas de moyen efficace de le faire pour les gros fichiers : unix.stackexchange.com/questions/87772/

0 votes

Pourriez-vous jeter un coup d'œil à cette méthode superuser.com/a/1352628/11116

506voto

Damian Powell Points 315

Linux :

echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt

または

sed -i '1s/^/task goes here\n/' todo.txt

または

sed -i '1itask goes here' todo.txt

Mac os x :

sed -i '.bak' '1s/^/task goes here\'$'\n/g' todo.txt

または

echo -e "task goes here\n$(cat todo.txt)" > todo.txt

または

echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt

8 votes

La première fonctionne très bien ! pourriez-vous expliquer la logique ? je ne suis pas particulièrement sûr de savoir comment interpréter la syntaxe.

63 votes

@user8347 : Pipe ( | ) le message ( echo '...' ) à cat qui utilise - (entrée standard) comme premier fichier et todo.txt comme le second. cat conCatène plusieurs fichiers. Envoyez la sortie ( > ) dans un fichier nommé temp . S'il n'y a pas d'erreurs ( && ) de cat puis renommer ( mv ) le temp pour revenir au fichier d'origine ( todo.txt ).

0 votes

Le chat pourrait être un problème s'il rencontre \n

94voto

John Alberts Points 1041

Une option plus simple à mon avis est :

echo -e "task goes here\n$(cat todo.txt)" > todo.txt

Cela fonctionne parce que la commande à l'intérieur de $(...) est exécuté avant todo.txt est remplacé par > todo.txt

Bien que les autres réponses fonctionnent bien, je trouve celle-ci beaucoup plus facile à retenir car j'utilise écho et chat tous les jours.

EDITAR: Cette solution est une très mauvaise idée s'il y a des backslashes dans todo.txt car grâce à la -e L'écho du drapeau les interprétera. Une autre façon, bien plus simple, d'introduire des retours à la ligne dans la chaîne de préface est...

echo "task goes here
$(cat todo.txt)" > todo.txt

...simplement d'utiliser des sauts de ligne. Bien sûr, ce n'est plus une ligne unique, mais de façon réaliste, ce n'était pas non plus une ligne unique avant. Si vous faites ceci à l'intérieur d'un script, et que vous êtes préoccupé par l'indentation (par exemple, si vous exécutez ceci à l'intérieur d'une fonction), il y a quelques solutions de contournement pour que cela s'adapte bien, y compris mais sans s'y limiter :

echo 'task goes here'$'\n'"$(cat todo.txt)" > todo.txt

De plus, si vous vous souciez de savoir si une nouvelle ligne est ajoutée à la fin de la commande todo.txt ne les utilisez pas. Enfin, sauf l'avant-dernière. Ça ne gâche pas la fin.

1 votes

Je n'obtiens pas du tout l'exécution de $(...).

2 votes

Cela fonctionnerait peut-être mieux (ou pas du tout) avec des guillemets doubles au lieu de simples

5 votes

Est-ce que le -e convertir également les séquences d'échappement dans le fichier todo.txt ?

34voto

slhck Points 209720

Le site moreutils ont un bel outil appelé sponge :

echo "task goes here" | cat - todo.txt | sponge todo.txt

Il "absorbera" STDIN et écrira ensuite dans le fichier, ce qui signifie que vous n'avez pas à vous soucier des fichiers temporaires et de leur déplacement.

Vous pouvez obtenir moreutils avec de nombreuses distributions Linux, grâce à apt-get install moreutils ou, sous OS X, en utilisant Homebrew avec brew install moreutils .

0 votes

Je choisirais (echo 'ble'; cat todo.txt) :-)

0 votes

J'utiliserais tee au lieu de l'éponge qui est fournie par défaut sur la plupart des distro echo "task goes here" | cat - todo.txt | tee todo.txt

1 votes

El tee l'exemple n'est pas correct askubuntu.com/a/752451

16voto

Red Tux Points 2074

Vous pouvez utiliser l'outil POSIX ex :

ex a.txt <<eof
1 insert
Sunday
.
xit
eof

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

5voto

Keith Points 7743

Vous pouvez créer un nouveau fichier temporaire.

echo "new task" > new_todo.txt
cat todo.txt >> new_todo.txt
rm todo.txt
mv new_todo.txt todo.txt

Vous pouvez également utiliser sed ou awk . Mais en gros, la même chose se produit.

2 votes

Disons que vous n'avez plus d'espace disque pour que new_todo.txt n'est écrit que partiellement. Votre solution semble perdre le fichier original.

1 votes

Qui manque d'espace disque ? ;-) Il s'agit d'un exemple simple.

2 votes

@Keith Quelqu'un travaillant sur une VM qui ne s'attendait pas à avoir besoin d'un disque virtuel particulièrement grand. Ou quelqu'un qui déplace un gros fichier. Dans tous les cas, le véritable argument contre cela est les permissions de répertoire ; si vous n'avez pas la permission de créer de nouveaux fichiers dans le répertoire donné, la seule commande qui s'exécutera avec succès dans votre script est la commande rm du fichier original.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X