Question 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. je suis conscient de echo 'task goes here' >> todo.txt mais cela ajoute la ligne à la fin du fichier (pas ce que je veux).


228
2018-02-17 03:21


origine


Il n'y a pas de moyen efficace de le faire pour les gros fichiers: unix.stackexchange.com/questions/87772/ - Ciro Santilli 新疆改造中心 六四事件 法轮功
Si tu regardais cette méthode superuser.com/a/1352628/11116 - Evan Carroll


Réponses:


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

ou

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

ou

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

304
2018-02-17 03:34



le premier fonctionne bien! Cela vous dérangerait-il d'expliquer la logique? Je ne suis pas particulièrement sûr de savoir comment interpréter la syntaxe. - user479534
@ user8347: Pipe (|) le message (echo '...') à cat qui utilise - (entrée standard) comme premier fichier et todo.txt comme le second. cat conCatenate plusieurs fichiers. Envoyer la sortie (>) à un fichier nommé temp. S'il n'y a pas d'erreurs (&&) de cat puis renommer (mv) la temp retour au fichier d'origine (todo.txt). - Dennis Williamson
Je ne connaissais pas cette syntaxe possible dans le dernier exemple de sed, est-ce que quelqu'un peut me dire quel est le nom de ce type de syntaxe pour que je puisse en savoir plus? - Kira
@Kira: Le 1 signifie faire la commande suivante uniquement sur la ligne un du fichier et le i commande est insert. Regardez dans la page de manuel sous la section "Adresses" et dans la section "Commandes à zéro ou à une adresse". - Dennis Williamson
@Terrance: Si votre sed commande ressemble à ceci (en insérant une tabulation): '1i\tSome Text', vous devrez peut-être doubler la barre oblique inverse. Sinon, votre dialecte de sed peut ne pas reconnaître \t comme onglet. - Dennis Williamson


Une option plus simple à mon avis est la suivante:

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 écrasé par > todo.txt

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

MODIFIER: Cette solution est une très mauvaise idée s'il y a des barres obliques inverses dans todo.txt, parce que grâce à la -e flag echo les interprétera. Un autre moyen beaucoup plus facile d'obtenir de nouvelles lignes dans la chaîne de préface est ...

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

... simplement utiliser des nouvelles lignes. Bien sûr, ce n'est plus un monotone, mais ce n'était pas non plus une doublure. Si vous faites cela dans un script et que vous ne vous souciez pas de l'indentation (par exemple, vous l'exécutez dans une fonction), il existe quelques solutions pour que cela reste bien adapté, y compris, mais sans s'y limiter:

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

En outre, si vous vous souciez de savoir si une nouvelle ligne est ajoutée à la fin de todo.txt, ne les utilisez pas Eh bien, sauf l'avant-dernier. Cela ne gâche pas la fin.


59
2017-12-19 18:57



Je n'ai pas du tout exécuté $ (...). - SCL
Cela pourrait fonctionner mieux (ou pas du tout) avec des guillemets doubles plutôt que des guillemets simples ... - ℝaphink
Ne sera pas le -e convertit également les séquences d'échappement dans todo.txt? - mk12
Taux de contournement -> cat: <nom du fichier de destination>: le fichier d'entrée est un fichier de sortie ... - ingyhere
printf serait beaucoup plus cohérent sur toutes les plates-formes et devrait généralement fonctionner plus facilement que echo -e - Peter Berg


le moreutils avoir un bel outil appelé sponge:

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

Il va "absorber" STDIN et ensuite écrire dans le fichier, ce qui signifie que vous n'avez pas à vous soucier des fichiers temporaires et à les déplacer.

Tu peux recevoir moreutils avec de nombreuses distributions Linux, via apt-get install moreutils, ou sur OS X en utilisant Homebrew, avec brew install moreutils.


26
2018-04-22 12:47





Vous pouvez utiliser Vim en mode Ex:

ex -sc '1i|task goes here' -cx todo.txt
  1. 1 sélectionnez la première ligne

  2. i insérer

  3. x sauver et fermer


5
2018-04-11 00:23





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 pourriez aussi utiliser sed ou awk. Mais fondamentalement, la même chose se produit.


3
2018-02-17 03:26



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 d'origine. - NPE
Qui manque d'espace disque? ;-) C'est juste un exemple simple. - Keith
@Keith Quelqu'un travaillant sur une VM qui ne s'attendait pas à avoir besoin d'un lecteur virtuel particulièrement volumineux. Ou quelqu'un qui déplace un gros fichier. Dans tous les cas, le véritable argument contre cela est les autorisations de répertoire; Si vous n'êtes pas autorisé à créer de nouveaux fichiers dans le répertoire donné, la seule commande qui sera exécutée avec succès dans votre script est la suivante: rm du fichier d'origine. - Parthian Shot


Si le fichier texte est suffisamment petit pour tenir en mémoire, vous n'avez pas besoin de créer un fichier temporaire pour le remplacer. Vous pouvez tout charger en mémoire et le réécrire dans le fichier.

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

Il est impossible d'ajouter des lignes au début du fichier sans écraser le fichier entier.


3
2018-01-09 22:49



Juste pour poser la question évidente: Où est la limite de caractères des variables shell? - nixda
Autant que je sache, il est seulement limité par la quantité de mémoire disponible. J'ai rempli des variables bien au-delà de 100 Mo en mémoire. text=$(cat file). Attention à n'utiliser que du texte, car les variables shell ne sont pas propres aux binaires mywiki.wooledge.org/BashFAQ/058 - Rucent88


Vous ne pouvez pas insérer de contenu au début d'un fichier. La seule chose que vous pouvez faire est soit remplacer le contenu existant ou ajouter des octets après la fin du fichier en cours.

Toute solution à votre question nécessite alors la création d'un fichier temporaire (ou tampon) (en mémoire ou sur disque) qui écrasera éventuellement le fichier d'origine.

Méfiez-vous de ne pas perdre de données en conservant le fichier original lors de la création du nouveau, si le système de fichiers est saturé pendant le processus. par exemple:

cat <(echo task go there) todo.txt > todo.txt.new && mv todo.txt.new todo.txt

2
2018-02-17 06:25



Les downvoters sont invités à expliquer leur motivation. Aucune des réponses restantes, y compris celle acceptée, ne contredit quoi que ce soit dans ma réponse. - jlliagre
C'est difficile à analyser car les <...> ressemblent à des crochets, ce que je suppose qu'ils ne le sont pas. Un espace entre le <et le (pourrait aider?) - dumbledad
Cela ne fonctionne pas pour moi. echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile' travaille mais cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile' donne l'erreur "echo: No such file or directory" - dumbledad
@dumbledad Vous pensez trop à ma réponse. Il n'y a rien à analyser. Un espace entre le < et le ( briserait la syntaxe. Essayer cat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile' - jlliagre


Vous pouvez utiliser tee:

echo 'task goes here' | cat - todo.txt | tee todo.txt

0
2017-07-08 14:16



Non tu ne peux pas askubuntu.com/a/752451 - Steven Penny


GitBash + Windows10 + Multline:

Voici une version qui vous permet d'utiliser cordes multi-lignes.

##############################################
## This section for demo purpose only,      ##
## So you can save entire file as           ##
## whatever.sh and run it.                  ##
##                                          ##
##############################################
> MY_TARGET_FILE.txt ##Make Or Clear File
echo "[STARTER_CONTENT]" >> MY_TARGET_FILE.txt
##############################################

## Below is main code:

##################################################
TARGET_FILE_VARIABLE="MY_TARGET_FILE.txt"
ADD_TO_HEAD_VARIABLE=$(cat << "HEREDOC_HEAD_TEXT"
//|  +-------------------------------------+   |//
//|  |                                     |   |//
//|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
//|  |                                     |   |//
//|  +-------------------------------------+   |//
HEREDOC_HEAD_TEXT
)
##################################################
TAR=$TARGET_FILE_VARIABLE                       ##
TEX=$ADD_TO_HEAD_VARIABLE                       ##
echo "$TEX" | cat - $TAR > TEMP && mv TEMP $TAR ##
##################################################

## Expected contents of MY_TARGET_FILE.txt :
## //|  +-------------------------------------+   |//
## //|  |                                     |   |//
## //|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
## //|  |                                     |   |//
## //|  +-------------------------------------+   |//
## [STARTER_CONTENT]

0
2017-08-04 07:04