commande sed en exécution à sec

Je ne suis pas en mesure de savoir si et comment il est possible de faire une course à sec avec sed.

J'ai donc cette commande:

find ./ -type f | xargs sed -i 's/string1/string2/g'

Mais avant de vraiment substituer dans tous les fichiers, Je veux vérifier ce qu'il remplacerait. Copier toute la structure du répertoire pour vérifier n'est pas une option!

Merci pour toute rétroaction (négative ou positive:))

31
demandé sur dmeu 2010-12-22 23:55:11

3 réponses

Supprimez le -i et dirigez-le vers less pour paginer les résultats. Vous pouvez également rediriger le tout vers un fichier volumineux en supprimant le -i et en ajoutant > dryrun.out

Je devrais noter que votre script échouera lamentablement avec des fichiers qui contiennent des espaces dans leur nom ou d'autres caractères infâmes comme les nouvelles lignes ou autres joyeusetés. Une meilleure façon de le faire serait:

while IFS= read -r -d $'\0' file; do
  sed -i 's/string1/string2/g' "$file"
done < <(find ./ -type f -print0)
26
répondu SiegeX 2010-12-22 21:07:57

Je préférerais utiliser l'option p:

find ./ -type f | xargs sed 's/string1/string2/gp'

Peut être combiné avec le paramètre -- quiet pour une sortie moins détaillée:

find ./ -type f | xargs sed --quiet 's/string1/string2/gp'

À Partir de man sed:

P:

Affiche l'espace de motif actuel.

--calme:

Supprimer l'impression automatique de l'espace de motif

10
répondu Murmel 2015-06-23 19:55:30

Je sais que c'est un très vieux fil et que L'OP n'a pas vraiment besoin de cette réponse, mais je suis venu ici à la recherche d'un mode de fonctionnement à sec moi-même, alors j'ai pensé à ajouter le Conseil ci-dessous pour tous ceux qui viendront ici à l'avenir. Ce que je voulais faire était d'éviter de piétiner le fichier de sauvegarde à moins que quelque chose ne change vraiment. Si vous exécutez aveuglément sed en utilisant l'option -i avec le suffixe de sauvegarde, le fichier de sauvegarde existant est écrasé, même s'il n'y a rien de substitué.

La façon dont j'ai fini par faire est de diriger la sortie sed vers diff et de voir si quelque chose a changé, puis de réexécuter sed avec l'option de mise à jour sur place, quelque chose comme ceci:

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    sed -i.bak -e 's/string1/string2/g' $fpath
fi

Selon la question de L'OP, si l'exigence est de voir ce qui changerait, alors au lieu d'exécuter le sed in-pace, vous pourriez refaire le diff avec quelques messages informatifs:

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    echo "File $fpath will change with the below diff:"
    sed -e 's/string1/string2/g' $fpath | diff $fpath -
fi

Vous pouvez également capturer la sortie dans une variable pour éviter de le faire deux fois:

diff=$(sed -e 's/string1/string2/g' $fpath | diff $fpath -)
if [[ $? -ne 0 ]]; then
    echo "File $fpath will change with the below diff:"
    echo "$diff"
fi
4
répondu haridsv 2016-05-12 07:49:01