MISE À JOUR: le script python de loevborg est certainement la solution la plus simple et la meilleure (il n'y a aucun doute à ce sujet) et je suis très satisfait, mais je tiens à souligner que le script bash que j'ai présenté (à la fin de la question) n'est pas aussi compliqué qu'il n'y paraît.. J'ai éliminé tout le bavardage de débogage que j'ai utilisé pour le tester.. et le voici à nouveau sans le fardeau inutile (pour quiconque visite cette page).. C'est essentiellement une commande en une ligne avec sed
, avec des conversions hexadécimales pré et post- :
F=("$haystack" "$needle" "$replacement")
for f in "${F[@]}" ; do cat "$f" | hexdump -v -e '1/1 "%02x"' > "$f.hex" ; done
sed -i "s/$(cat "${F[1])}.hex")/$(cat "${F[2])}.hex")/p" "${F[0])}.hex"
cat "${F[0])}.hex" | xxd -r -p > "${F[0])}"
# supprimer les fichiers temporaires *.hex.
Juste pour apporter ma contribution, j'ai trouvé une solution avec 'sed' qui ne rencontrera aucun problème avec les caractères spéciaux, car elle n'en utilise pas un seul ! .. au lieu de cela, elle fonctionne sur des versions hexadécimales des fichiers...
Je trouve que c'est un peu trop "lourd", mais cela fonctionne, et n'est apparemment pas limité par des restrictions de taille.. GNU sed a une taille de tampon de modèle illimitée, et c'est là que se retrouve le bloc de lignes de recherche hexadécimal.. Donc c'est bien de ce côté-là...
Je cherche toujours une solution diff
, car elle sera plus flexible concernant l'espace blanc (et je m'attends à ce qu'elle soit plus rapide)... mais en attendant.. C'est le célèbre M. Sed. :)
Ce script fonctionne entièrement tel quel, et est raisonnablement commenté...
Il semble plus grand qu'il ne l'est; il comporte seulement sept lignes de code essentielles.
Pour un test semi-réaliste, il télécharge le livre "Alice au Pays des Merveilles" depuis Project Gutenberg (363,1 Ko) ... et remplace le poème original du Jabberwocky par une version inversée.. (Curieusement, ce n'est pas très différent de le lire à l'envers :)
PS. Je viens de réaliser qu'une faiblesse de cette méthode est si votre original utilise \r\n (0xODOA) comme sa fin de ligne, et que votre "texte à rechercher" est enregistré avec \n (0x0A).. alors ce processus de recherche est voué à l'échec... ('diff' n'a pas de tels problèmes) ...
# Dans un fichier texte, remplacez un bloc de lignes par un autre bloc
#
# En restant sur le thème du 'Jabberwocky',
# et en utilisant 'sed' avec 'hexdump', afin qu'il n'y ait aucun risque de collision avec des caractères *spéciaux*.
#
# La configuration actuelle ne remplacera que la première occurrence.
# En utilisant la commande 'g' de sed, cela peut changer toutes les occurrences.
#
lookinglass="$HOME/De l'autre côté du miroir de Lewis Carroll"
jabberwocky="$lookinglass (jabberwocky)"
ykcowrebbaj="$lookinglass (ykcowrebbaj)"
##### Cette section EST UNIQUEMENT POUR LA PRÉPARATION DES TESTS
fromURL="http://www.gutenberg.org/ebooks/12.txt.utf8"
wget $fromURL -O "$lookinglass"
if (($?==0))
then echo "Téléchargement OK"
else exit 1
fi
# Faire une sauvegarde de l'original (pendant les tests)
cp "$lookinglass" "$lookinglass (depuisURL)"
#
# Extraire le poème et l'écrire dans un fichier. (Il s'exécute de la ligne 322-359)
sed -n 322,359p "$lookinglass" > "$jabberwocky"
cat "$jabberwocky"; read -p "Ceci est l'original.. (appuyez sur Entrée pour continuer)"
#
# Créer un fichier contenant un bloc de lignes de remplacement
tac "$jabberwocky" > "$ykcowrebbaj"
cat "$ykcowrebbaj"; read -p "Ceci est le REMPLACEMENT.. (appuyez sur Entrée pour continuer)"
##### Fin de la PRÉPARATION DES TESTS
# Le processus principal
#
# Créer des versions 'hexdump' des 3 fichiers... source, attendu, de remplacement
cat "$lookinglass" | hexdump -v -e '1/1 "%02x"' > "$lookinglass.xdig"
cat "$jabberwocky" | hexdump -v -e '1/1 "%02x"' > "$jabberwocky.xdig"
cat "$ykcowrebbaj" | hexdump -v -e '1/1 "%02x"' > "$ykcowrebbaj.xdig"
# Maintenant utiliser 'sed' de manière sûre (pas de caractères spéciaux).
# Remarque, tous les fichiers sont maintenant chacun, une seule ligne ('\n' est maintenant '0A')
sed -i "s/$(cat "$jabberwocky.xdig")/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
##### Cette section EST UNIQUEMENT POUR VÉRIFIER LES RÉSULTATS
# Vérifier le résultat 1
read -p "Sur le point de tester la présence de 'jabberwocky.xdig' en lui-même (Entrée) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$jabberwocky.xdig"
echo -e "\n\nUn affichage au-dessus de cette ligne signifie: 'jabberwocky' est comme prévu\n"
# Vérifier le résultat 2
read -p "Sur le point de tester la présence de 'ykcowrebbaj.xdig' en lui-même (Entrée) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$ykcowrebbaj.xdig"
echo -e "\n\nUn affichage au-dessus de cette ligne signifie: 'ykcowrebbaj' est comme prévu\n"
# Vérifier le résultat 3
read -p "Sur le point de tester la présence de 'lookinglass.xdig' en lui-même (Entrée) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nUn affichage au-dessus de cette ligne signifie: 'lookinglass' est comme prévu\n"
# Vérifier le résultat 4
read -p "Sur le point de tester la présence de 'lookinglass.xdig' en lui-même (Entrée) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nAucun affichage au-dessus de cette ligne signifie: 'lookinglass' est comme prévu\n"
##### Fin de la VÉRIFICATION DES RÉSULTATS
# Convertir maintenant le hexdump en binaire, et écraser l'original
cat "$lookinglass.xdig" | xxd -r -p > "$lookinglass"
# Afficher le poème "modifié" à l'écran
sed -n 322,359p "$lookinglass"
echo -e "\n\nVous regardez maintenant le texte DE REMPLACEMENT (extraite directement du 'livre' source"