Comment supprimer le caractère de nouvelle ligne à la fin du fichier?

35

Permettez-moi de préciser le caractère de nouvelle ligne:

$ echo Hello > file1 ; cat file1
Hello
$ echo -n  Hello > file2 ; cat file2
Hello$ 

Ici, vous pouvez voir qu'il y file1a un caractère de nouvelle ligne à la fin, mais file2pas.

Supposons maintenant que j'en ai un file:

$ cat file
Hello
Welcome to
Unix
$

Et je veux ajouter and Linuxà la fin du fichier, puis echo " and Linux" >> filesera ajouté à la nouvelle ligne. Mais je veux que la dernière ligne soitUnix and Linux

Donc, pour contourner ce problème, je souhaite supprimer le caractère de nouvelle ligne à la fin du fichier. Par conséquent, comment supprimer le caractère de nouvelle ligne à la fin du fichier?

Pandya
la source
6
Ne le supprimez pas, utilisez simplement un éditeur de texte. sed '$s/$/ and linux/'
123

Réponses:

29

Si tout ce que vous voulez faire est d'ajouter du texte à la dernière ligne, c'est très simple avec sed. Remplacez $(correspondance de motif à la fin de la ligne) par le texte que vous souhaitez ajouter, uniquement sur les lignes de la plage $(ce qui signifie la dernière ligne).

sed '$ s/$/ and Linux/' <file >file.new &&
mv file.new file

qui sur Linux peut être raccourci

sed -i '$ s/$/ and Linux/' file

Si vous souhaitez supprimer le dernier octet d'un fichier, Linux (plus précisément GNU coreutils) propose la truncatecommande, ce qui rend cela très simple.

truncate -s -1 file

Une façon POSIX de le faire est avec dd. Déterminez d'abord la longueur du fichier, puis tronquez-la à un octet de moins.

length=$(wc -c <file)
dd if=/dev/null of=file obs="$((length-1))" seek=1

Notez que ces deux tronquent inconditionnellement le dernier octet du fichier. Vous voudrez peut-être d'abord vérifier qu'il s'agit d'une nouvelle ligne:

length=$(wc -c <file)
if [ "$length" -ne 0 ] && [ -z "$(tail -c -1 <file)" ]; then
  # The file ends with a newline or null
  dd if=/dev/null of=file obs="$((length-1))" seek=1
fi
Gilles 'SO- arrête d'être méchant'
la source
9
Le meilleur moyen de supprimer une nouvelle ligne de fin est perl -pi -e 'chomp if eof' myfile. Par rapport à truncateou ddça ne vous laissera pas un fichier cassé s'il myfilen'y avait en fait pas de retour à la ligne.
Hi-Angel
2
@ Hi-Angel Puis-je recommander d'écrire cela comme réponse? Je pense que ce serait une très bonne réponse.
Simon Forsberg
@SimonForsberg merci, c'est fait .
Hi-Angel,
17

Cependant, vous pouvez supprimer le caractère de nouvelle ligne de la ligne en tr -d '\n':

$ echo -e "Hello"
Hello
$ echo -e "Hello" | tr -d '\n'
Hello$

Vous pouvez supprimer le caractère de nouvelle ligne à la fin du fichier en utilisant la méthode simple suivante:

  1. head -c -1 file

    De man head:

    -c, --bytes=[-]K
              print the first K bytes of each file; with the leading '-',
              print all but the last K bytes of each file
  2. truncate -s -1 file

    de man truncate:

    -s, --size=SIZE
              set or adjust the file size by SIZE

    SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
    Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000).
    
    SIZE  may  also be prefixed by one of the following modifying characters: 
    '+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down to multiple of, '%' round up to multiple of.
Pandya
la source
est head -c -1 file | tee filesûr? Vous ne teesouhaitez pas tronquer le fichier avant de commencer?
iruvar
1
@ 1_CR En effet. Les deux côtés de la pipe partent en parallèle, c'est une question de qui gagne la course. Puisqu'il teesuffit d'ouvrir le fichier, alors qu'il headdoit lire et écrire son contenu, il teegagnera en pratique la course sauf parfois pour les très petits fichiers.
Gilles 'SO- arrête d'être méchant'
2
Cela ne supprime pas la dernière nouvelle ligne, il supprime toutes les nouvelles lignes. L'OMI fait une grande différence.
Hi-Angel
10

Vous pouvez y parvenir avec perl comme:

perl -pi -e 'chomp if eof' myfile

Comparé à truncateou ddcela ne vous laissera pas avec un fichier cassé s'il myfilen'y avait en fait aucun retour à la ligne.

(la réponse est construite à partir du commentaire et basée sur cette réponse )

Salut ange
la source
Je vous remercie! Cette méthode conditionnelle de suppression de la fin de ligne est parfaite.
xer0x
3

Voici une façon avec sed- sur la dernière ( $) ligne du fichier, recherchez et remplacez tout et n'importe quoi ( .*) par "ce que vous avez correspondu" suivi de "et Linux":

sed '$s/\(.*\)/\1 and Linux/' file

Une solution encore plus simple, gracieuseté d' Isaac , est:

sed '$s/$/ and Linux/' file

Ceci remplace la fin de ligne (symbolique) par le texte donné.

Jeff Schaller
la source
Isaac, j'aime cette suggestion! C'est plus simple / plus évident. Je mettrai à jour la réponse avec. Merci!
Jeff Schaller