passer par mktemp est effectivement plus propre pour le fichier temporaire.
Pour ce qui est de l'utilisation du perl, j'avais fais ça uniquement afin d'empêcher l'utilisation des regexp dans la chaîne à remplacer. J'utilise souvent cette fonction et quoter tous les caractères spéciaux "[]*.(|)\..." serait vite pénible. Cela dit il existe d'autres solutions que le perl pour cela, on pourrait par exemple faire un "echo toto | sed -e 's:\(.\):\\\1:g'" pour protéger tous les caractères (comme je ne suis pas sur de l'ordre d'évaluation d'une expression par perl, ça serait peut-être même mieux).
Si vous voyez une meilleure solution, n'hésitez pas
D'autre part, le '&&' sert a n'exécuter la commande qui suit que si la commande précédente s'est déroulée sans problème (i.e. renvoit un code de retour de 0).
Ainsi un
sed ... > $tmp
mv $tmp $1
peut causer des pertes de données si le disk se remplit pendant le sed (ce qui arrive parfois avec les systèmes multi-utilisateur).
Il faut donc faire "sed ... > $tmp && mv $tmp $1"
Enfin, il est inutile de faire "cat fichier | sed ", c'est ce qu'on pourrait appeller en français une utilisation abusive de cat (Useless Use of Cat Award). Il convient de faire directement "sed fichier".
Pendant que j'y suis je note aussi une utilisation abusive de "ls" : il faut utiliser directement "*" et non "`ls`". De surcroit, l'utilisation de ls entraine des erreurs avec les noms de fichiers contenant des espaces.
De même, on n'écrit jamais $variable quand la variable contient un nom de fichier (qui contient potentiellemnt des espaces ou autre caractère "spécial" ) mais "$variable".
Pour plus de détails, je ne saurais que trop vous conseiller la lecture d'un bon livre sur le shell et les shell-script.