J'ai un simple shell script qui supprime les espaces blancs de fin de fichier. Existe-t-il un moyen de rendre ce script plus compact (sans créer un fichier temporaire) ?
sed 's/[ \t]*$//' $1 > $1__.tmp
cat $1__.tmp > $1
rm $1__.tmp
J'ai un simple shell script qui supprime les espaces blancs de fin de fichier. Existe-t-il un moyen de rendre ce script plus compact (sans créer un fichier temporaire) ?
sed 's/[ \t]*$//' $1 > $1__.tmp
cat $1__.tmp > $1
rm $1__.tmp
Pour ceux qui recherchent l'efficacité (beaucoup de fichiers à traiter, ou des fichiers énormes), l'utilisation de la fonction +
opérateur de répétition au lieu de *
rend la commande plus de deux fois plus rapide.
Avec GNU sed :
sed -Ei 's/[ \t]+$//' "$1"
sed -i 's/[ \t]\+$//' "$1" # The same without extended regex
J'ai également procédé à une analyse comparative rapide d'un autre aspect : en utilisant [ \t]
au lieu de [[:space:]]
accélère également le processus de manière significative (GNU sed v4.4) :
sed -Ei 's/[ \t]+$//' "$1"
real 0m0,335s
user 0m0,133s
sys 0m0,193s
sed -Ei 's/[[:space:]]+$//' "$1"
real 0m0,838s
user 0m0,630s
sys 0m0,207s
sed -Ei 's/[ \t]*$//' "$1"
real 0m0,882s
user 0m0,657s
sys 0m0,227s
sed -Ei 's/[[:space:]]*$//' "$1"
real 0m1,711s
user 0m1,423s
sys 0m0,283s
Dans le cas spécifique de sed
le -i
L'option que d'autres ont déjà mentionnée est de loin la plus simple et la plus saine.
Dans le cas plus général, sponge
à partir du moreutils
fait exactement ce que vous voulez : il vous permet de remplacer un fichier par le résultat de son traitement, d'une manière spécifiquement conçue pour éviter que l'étape de traitement ne se renverse en écrasant le fichier sur lequel elle travaille. Pour citer le sponge
page de manuel :
sponge lit l'entrée standard et l'écrit dans le fichier spécifié. Contrairement à une redirection shell, sponge absorbe toute son entrée avant d'écrire le fichier de sortie. Cela permet de construire des pipelines qui lisent et écrivent dans le même fichier.
Juste pour le plaisir :
#!/bin/bash
FILE=$1
if [[ -z $FILE ]]; then
echo "You must pass a filename -- exiting" >&2
exit 1
fi
if [[ ! -f $FILE ]]; then
echo "There is not file '$FILE' here -- exiting" >&2
exit 1
fi
BEFORE=`wc -c "$FILE" | cut --delimiter=' ' --fields=1`
# >>>>>>>>>>
sed -i.bak -e's/[ \t]*$//' "$FILE"
# <<<<<<<<<<
AFTER=`wc -c "$FILE" | cut --delimiter=' ' --fields=1`
if [[ $? != 0 ]]; then
echo "Some error occurred" >&2
else
echo "Filtered '$FILE' from $BEFORE characters to $AFTER characters"
fi
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.