Disons que j'ai un fichier texte multiligne arbitraire:
sometext
moretext
lastline
Comment puis-je supprimer uniquement le dernier caractère (le e, pas la nouvelle ligne ou la valeur null) du fichier sans rendre le fichier texte invalide?
truncate
truncate -s-1 file
Supprime un (-1) caractère de la fin du même fichier. Exactement comme un >>
sera ajouté au même fichier.
Le problème avec cette approche est qu’elle ne conserve pas de nouvelle ligne s’il existe.
La solution est:
if [ -n "$(tail -c1 file)" ] # if the file has not a trailing new line.
then
truncate -s-1 file # remove one char as the question request.
else
truncate -s-2 file # remove the last two characters
echo "" >> file # add the trailing new line back
fi
Cela fonctionne car tail prend le dernier octet (pas de caractère).
Cela ne prend presque pas de temps, même avec de gros fichiers.
Pourquoi pas sed
Le problème avec une solution sed telle que sed '$ s/.$//' file
est qu’il lit d’abord le fichier entier (cela prend du temps avec des fichiers volumineux), puis vous avez besoin d’un fichier temporaire (de la même taille que l’original):
sed '$ s/.$//' file > tempfile
rm file; mv tempfile file
Puis déplacez le fichier temporaire pour remplacer le fichier.
Voici une autre utilisation de ex
, que je trouve moins cryptée que la solution sed:
printf '%s\n' '$' 's/.$//' wq | ex somefile
Le $
va à la dernière ligne, la s
supprime le dernier caractère et wq
est le bien connu (aux utilisateurs de vi) write + quit.
Si l'objectif est de supprimer le dernier caractère de la dernière ligne, cette awk
devrait faire:
awk '{a[NR]=$0} END {for (i=1;i<NR;i++) print a[i];sub(/.$/,"",a[NR]);print a[NR]}' file
sometext
moretext
lastlin
Il stocke toutes les données dans un tableau, puis l'imprime et modifie la dernière ligne.
Juste une remarque: sed supprimera temporairement le fichier . Ainsi, si vous réduisez le fichier, vous recevrez un avertissement "Aucun fichier ou répertoire de ce type" jusqu'à ce que vous réémettiez la commande tail.
RÉPONSE RÉVISÉE
J'ai créé un script et mis votre texte à l'intérieur de mon bureau. ce fichier de test est enregistré sous "old_file.txt"
sometext
moretext
lastline
Après, j’ai écrit un petit script pour récupérer l’ancien fichier et éliminer le dernier caractère de la dernière ligne
#!/bin/bash
no_of_new_line_characters=`wc '/root/Desktop/old_file.txt'|cut -d ' ' -f2`
let "no_of_lines=no_of_new_line_characters+1"
sed -n 1,"$no_of_new_line_characters"p '/root/Desktop/old_file.txt' > '/root/Desktop/my_new_file'
sed -n "$no_of_lines","$no_of_lines"p '/root/Desktop/old_file.txt'|sed 's/.$//g' >> '/root/Desktop/my_new_file'
ouvrant le nouveau_fichier que j'ai créé, affiche le résultat comme suit:
sometext
moretext
lastlin
Je m'excuse pour ma réponse précédente (je ne lisais pas attentivement)
Après tout un tas de jeux avec différentes stratégies (et en évitant sed -i ou Perl), le meilleur moyen que j'ai trouvé de faire cela était avec:
sed '$! { P; D; }; s/.$//' somefile
sed 's/.$//' filename | tee newFilename
Cela devrait faire votre travail.