web-dev-qa-db-fra.com

ajouter du texte avec écho sans nouvelle ligne

Je veux ajouter du texte au fichier comme echo "abc" >>file.txt.

Mais cela ajoute abc après la nouvelle ligne

Comment puis-je ajouter abc à la fin du fichier avec écho sans nouvelle ligne?

17
choijj

echo "abc" >>file.txt met une nouvelle ligne après abc, pas avant. Si vous vous retrouvez avec abc sur sa propre ligne, cela signifie que la nouvelle ligne avant abc était déjà présente dans file.txt.

Notez qu'il est parfaitement normal qu'un fichier texte se termine par une nouvelle ligne. Sous Unix, une ligne se compose d'une séquence de caractères autres que null⁰ ou newline suivie d'une nouvelle ligne.1 Par conséquent, tout fichier texte non vide se termine par un caractère de nouvelle ligne.

Si vous souhaitez ajouter du texte à la dernière ligne d'un fichier, vous ne pouvez pas le faire avec >>, car cela s'ajoute toujours au fichier, donc il écrit toujours après la dernière nouvelle ligne. Au lieu de cela, vous avez besoin d'un outil capable de modifier un fichier existant. Par exemple, vous pouvez utiliser sed :

sed '$ s/$/abc/' file.txt >file.txt.new && mv file.txt.new file.txt

Dans la commande sed, le premier $ signifie "exécuter la commande suivante uniquement sur la dernière ligne", la commande s/REGEX/REPLACEMENT/ remplace REGEX par REPLACEMENT, et l'expression régulière $ correspond à la fin de la ligne.

La commande sed de Linux a une fonction intégrée pour automatiser cette séquence de création de nouveau fichier et de remplacement, vous pouvez donc la raccourcir en

sed -i '$ s/$/abc/' file.txt

⁰ Il s'agit d'un octet nul, qui ASCII appelle NUL et Unicode appelle U + 0000. Les programmes de traitement de texte peuvent ou non gérer ce caractère.
1Voir les définitions de Fichier texte , Ligne , et Caractère de nouvelle ligne dans la section "Définitions" du chapitre Définitions de base de IEEE 1003.1-2008 : 2016.

En supposant que le fichier ne se termine pas déjà par une nouvelle ligne et que vous souhaitez simplement ajouter du texte sans en ajouter un, vous pouvez utiliser l'argument -n, Par exemple.

echo -n "some text here" >> file.txt

Cependant, certains systèmes UNIX ne proposent pas cette option; si tel est le cas, vous pouvez utiliser printf, par exemple.

printf %s "some text here" >> file.txt

(l'argument initial %s étant de se prémunir contre le texte supplémentaire contenant des caractères de formatage %)

Depuis man echo (Sur macOS High Sierra):

- n

N'imprimez pas le caractère de fin de ligne. Ceci peut également être réalisé en ajoutant '\c' À la fin de la chaîne, comme cela est fait par les systèmes compatibles iBCS2. Notez que cette option ainsi que l'effet de '\c' Sont définis par l'implémentation dans IEEE Std 1003.1-2001 ("POSIX.1") tel que modifié par le Cor. 1-2002. Les applications visant une portabilité maximale sont fortement encouragées à utiliser printf(1) pour supprimer le caractère de nouvelle ligne.

16
fluffy

Je ne pense pas que ce soit possible avec la commande echo, utilisez plutôt l'approche sed suivante:

sed -i '$ s/$/abc/' file.txt
  • -i - modifier le fichier en place
  • $ - indique le dernier enregistrement/la dernière ligne
  • s/$/abc/ - remplace la fin de la ligne $ avec sous-chaîne abc (pour le dernier enregistrement)
15
RomanPerekhrest

Si vous avez la commande truncate et que votre fichier texte a NL comme dernier caractère, vous pouvez le supprimer puis ajouter votre texte comme ceci:

truncate --size -1 file.txt
echo "abc" >>file.txt

(Notez que truncate ne se soucie pas du contenu du fichier et, dans cet exemple, réduit simplement la taille du fichier d'un octet. Si votre dernier caractère n'est pas un octet unique, c'est-à-dire qu'il s'agit d'un caractère "large" à plusieurs octets, alors vous introduira la corruption.)

9
roaima

Ce que vous voulez, c'est l'ajouter à la fin de la dernière ligne, donc juste avant le délimiteur de cette dernière ligne, donc juste avant le dernier caractère du fichier.

Avec ksh93, Vous pouvez faire:

echo abc 1<> file >#((EOF - 1))

1<> Est l'opérateur standard pour ouvrir un fichier en mode lecture + écriture (et surtout sans troncature) sur stdout et >#((...)) est spécifique à ksh93 - recherche opérateur (ici pour rechercher avant le dernier octet). Notez que echo écrit abc<newline>a écrase la nouvelle ligne qui était là et echo ajoute sa propre nouvelle ligne.

L'équivalent zsh:

zmodload zsh/system
{sysseek -w end -u 1 -1 && echo abc} 1<> file

Bien que pour un équivalent plus exact, vous devrez également imprimer un message d'erreur en cas d'échec de la recherche:

zmodload zsh/system
if sysseek -w end -u 1 -1; then
  echo abc
else
  syserror -p "$0: $LINENO: seek: "
fi 1<> file
5
Stéphane Chazelas