J'ai un script bash qui énumère tous les fichiers *.php d'un répertoire et applique iconv
à cela. Cela obtient la sortie dans STDOUT.
Depuis l'ajout du -o
Le paramètre (d'après mon expérience) écrit en fait un fichier vide probablement avant que la conversion n'ait lieu, comment puis-je ajuster mon script pour qu'il effectue la conversion, puis écrase le fichier d'entrée ?
for file in *.php
do
iconv -f cp1251 -t utf8 "$file"
done
Réponse acceptée :
Cela ne fonctionne pas car iconv
crée d'abord le fichier de sortie (puisque le fichier existe déjà, il le tronque), puis commence à lire son fichier d'entrée (qui est maintenant vide). La plupart des programmes se comportent de cette façon.
Créez un nouveau fichier temporaire pour la sortie, puis déplacez-le en place.
for file in *.php
do
iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
mv -f "$file.new" "$file"
done
Si l'iconv
de votre plate-forme n'a pas -o
, vous pouvez utiliser une redirection shell pour le même effet.
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
mv -f "$file.new" "$file"
done
L'sponge
de Colin Watson (inclus dans les moreutils de Joey Hess) automatise ceci :
for file in *.php
do
iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done
Cette réponse s'applique non seulement à iconv
mais à n'importe quel programme de filtrage. Quelques cas particuliers méritent d'être mentionnés :
- GNU sed et Perl
-p
avoir un-i
possibilité de remplacer les fichiers en place. - Si votre fichier est extrêmement volumineux, votre filtre modifie ou supprime uniquement certaines parties, mais n'ajoute jamais d'éléments (par exemple,
grep
,tr
,sed 's/long input text/shorter text/'
), et que vous aimez vivre dangereusement, vous voudrez peut-être véritablement modifier le fichier en place (les autres solutions mentionnées ici créent un nouveau fichier de sortie et le mettent en place à la fin, de sorte que les données d'origine restent inchangées si la commande est interrompue pendant pour quelque raison que ce soit).