Ce problème est probablement dû à une incompatibilité d'encodage entre le fichier d'entrée et le script awk script.
Notez tout d'abord qu'il y a probablement une confusion (très courante) entre ISO-8859-1 et Windows-1252. L'exemple html dans le post original contient des caractères em/en qui ne font pas partie de la norme ISO-8859-1. ISO-8859-1 mise en page Il utilise donc certainement un autre encodage, probablement Windows-1252 (qui est un surensemble d'ISO-8859-1 incluant les caractères tirets) puisque l'OP a déclaré utiliser Ubuntu à travers la couche du sous-système Windows.
Je supposerai alors que le fichier d'entrée html est effectivement encodé avec Windows-1252. Les caractères non ASCII (points de code 128) n'utilisent donc qu'un seul octet.
Si le programme awk est chargé à partir d'un fichier codé en UTF-8, ou même tapé directement dans une fenêtre de terminal qui utilise le codage UTF-8, les expressions régulières et les chaînes littérales intégrées dans le programme sont également codées en UTF-8. Les caractères non ASCII utilisent donc plusieurs octets.
Par exemple, le caractère §
(point de code 167 = 0xA7), est représenté par l'octet A7
dans Windows-1252 et la séquence d'octets C2 A7
en UTF-8. Si vous utilisez gsub(/§/, "S")
dans votre programme awk encodé en UTF-8, alors awk recherche la séquence C2 A7
dans le fichier d'entrée qui ne contient que des A7
. Il ne correspondra pas. À moins que vous n'ayez la (mal)chance d'avoir un caractère Â
(point de code 194 = 0xC2) juste avant que vous n'entriez dans la salle de réunion. §
.
Changer la locale n'est pas utile ici car cela indique seulement à awk comment analyser son entrée (données et programme), alors que ce dont vous avez besoin ici est de transcoder soit les données, soit les expressions régulières. Pour que cela fonctionne, il faudrait pouvoir spécifier la locale des données indépendamment de la locale du programme, ce qui n'est pas supporté.
Ainsi, en supposant que votre système est configuré avec une locale UTF-8 et que votre awk script utilise cette locale (qu'il soit chargé depuis un fichier ou tapé dans un terminal), voici plusieurs méthodes que vous pouvez utiliser pour aligner le fichier d'entrée et les expressions régulières sur le même encodage, de sorte que gsub
fonctionne comme prévu.
Notez que ces suggestions s'appliquent à votre première commande awk, car c'est elle qui est à l'origine du problème. Le dernier tuyau vers iconv
n'est nécessaire que si vous ne transformez pas intentionnellement tous les caractères spéciaux que vous pouvez avoir dans l'entrée en entités html. Dans le cas contraire, la sortie de awk est de l'ASCII pur et simple, donc déjà compatible avec UTF-8.
Option 1 : convertir le fichier d'entrée de Windows-1252 à UTF-8
Pas besoin d'un autre iconv
après cela en tout état de cause.
iconv -f WINDOWS-1252 t.html | awk '{
gsub(/charset=iso-8859-1/, "charset=UTF-8")
gsub(/\047/, "\\'")
gsub(/\*/, "\\*")
gsub(/–/, "\\–")
gsub(/—/, "\\—")
gsub(/§/, "\\§")
gsub(/«/, "\\«")
gsub(/»/, "\\»")
gsub(/¿/, "\\¿")
gsub(/Á/, "\\Á")
print
}'
Option 2 : convertir le programme awk de UTF-8 à Windows-1252
Parce que le programme awk peut aussi vouloir s'amuser. Utilisons la substitution de processus.
awk -f <(iconv -t WINDOWS-1252 <<'EOS'
{
gsub(/charset=iso-8859-1/, "charset=UTF-8")
gsub(/'/, "\\'")
gsub(/\*/, "\\*")
gsub(/–/, "\\–")
gsub(/—/, "\\—")
gsub(/§/, "\\§")
gsub(/«/, "\\«")
gsub(/»/, "\\»")
gsub(/¿/, "\\¿")
gsub(/Á/, "\\Á")
print
}
EOS
) t.html
Option 3 : enregistrer l'awk/schell script dans un fichier encodé en Windows-1252
... avec votre outil préféré.
Option 4 : changer l'encodage de votre session de terminal pour Windows-1252
Si vous tapez/collez la commande awk dans un terminal, bien sûr.
Notez que cela diffère de la définition de la locale (LC_CTYPE). Je n'ai pas connaissance d'un moyen de faire cela par programme. Si quelqu'un le sait, n'hésitez pas à contribuer.
Option 5 : éviter les caractères non ASCII dans le programme awk
Il s'agit en tout cas d'une bonne pratique à mon avis.
awk '{
gsub(/charset=iso-8859-1/, "charset=UTF-8")
gsub(/\047/, "\\'")
gsub(/\*/, "\\*")
gsub(/\226/, "\\–")
gsub(/\227/, "\\—")
gsub(/\247/, "\\§")
gsub(/\253/, "\\«")
gsub(/\273/, "\\»")
gsub(/\277/, "\\¿")
gsub(/\301/, "\\Á")
print
}' t.html