Remplacement des points (.) Dans sed

9

La vraie question est donc: est-ce que quelqu'un a une idée de comment supprimer M-BM-un caractère spécial sans risquer de perdre d'autres caractères?

J'ai une chaîne de texte:

" . . ."

C'est

space dot space dot space dot

J'essaie de remplacer toute occurrence de cette chaîne dans un fichier texte pour

"..."

C'est

dot dot dot

J'essayais de faire avec sed:

sed -r 's:\s\.\s\.\s\.:...:g' -i sed-dots

Malheureusement, cela ne change même pas un peu le fichier d'entrée. Fichier: https://www.dropbox.com/s/46zmiruy3ln85a1/sed-dots

Lorsque j'essaie de remplacer la même chaîne dans l'éditeur de texte (j'utilise geany), elle est trouvée et remplacée correctement.

La seule raison pour laquelle je peux penser est que certains (ou tous) de ces espaces ne sont pas vraiment des espaces, mais un caractère spécial.

Quelqu'un at-il une idée de comment trouver et remplacer cette chaîne par sed (ou tout autre outil en ligne de commande)? Veuillez tester votre idée sur mon fichier, car le problème n'est pas aussi évident qu'il y paraît - c'est pourquoi j'ai posé la question.

Après avoir utilisé cat -Amon fichier, il semble problématique que ces espaces ne soient pas des espaces, mais M-BM-des caractères spéciaux. L'utilisation d'un symbole .suggéré pour la recherche n'est pas une bonne idée car il existe un risque que d'autres caractères soient supprimés.

Rafal
la source

Réponses:

10

Tout d'abord, je commencerais par tester echoet canaliser cela sed, plutôt que d'utiliser un vrai fichier. Deuxièmement, vous pouvez utiliser un {n}dans le modèle regex étendu pour désigner les multiples et les limites.

Vous y étiez à peu près mais votre regex s'attendait à un espace de tête.

$ echo 'cheese . . . muffins' | sed -r 's/(\s?\.){3}/ dot dot dot/g'
cheese dot dot dot muffins

Notez que le \s?est toujours assez gourmand pour ruiner la sortie, j'ai donc ajouté un espace à la sortie. Vous pourriez ne pas vouloir ça. J'ai également rendu l'espace facultatif, il correspondra donc à tous les éléments suivants:

...
. ..
.. .
. . .
 . . . 

Retirez simplement le ?drapeau optionnel .


Compte tenu de votre problème avec l'unicode (dans les commentaires), vous pouvez forcer les données à leur équivalence ASCII avec iconvpuis les séduire:

$ iconv -f utf-8 -t ascii//translit sed-dots | sed -r 's/(\s?\.){3}/ dot dot dot/g'
Lorem ipsum dot dot dot
Some dot dot dot more text
Oli
la source
Je suis surpris que vous recommandiez d'utiliser echoau lieu de copier un fichier, au moins lorsque vous cat un fichier, vous savez que le shell n'interprète rien, et l'écho non plus.
Flimm
@Flimm pour un exemple simple avec des points, ce n'est pas vraiment un problème. Si vous allez charger à partir d'un fichier, ne vous embêtez pas cat- il suffit de sedcharger le fichier (selon l'exemple de l'OP) mais de ne pas l'enregistrer en ligne (supprimer -i, afin que vous puissiez voir et tester par rapport à la sortie).
Oli
@Oli Cela fonctionne avec votre exemple, mais cela ne fonctionne pas avec mon fichier (dans ma question, il y a un lien). C'est un problème - votre commande et d'autres devraient fonctionner, mais ce n'est pas le cas car il y a un problème avec ces points. Veuillez tester votre commande sur mon fichier et vous verrez qu'elle ne fonctionne pas.
Rafal
1
@Rafal Si vous regardez, cat -A sed-dotsvous pouvez voir que les "espaces" entre les points sont des M-BM- caractères spéciaux ... Je ne sais pas comment ils se sont glissés là-dedans mais ils doivent être remplacés. Si vous ne pouvez pas bien les cibler, cela fonctionne: sed -r 's/(\s\..\..\.)/ dot dot dot/ig' sed-dots
Oli
@Oli Ça marche. Merci beaucoup! Pourriez-vous expliquer la syntaxe? Êtes-vous sûr qu'il n'a aucun effet secondaire et ne remplacera rien d'autre? Pour autant que je vois, ce RegExp correspondra à n'importe quel caractère après les points. Cependant, M-BM n'est pas un personnage, c'est trois. Alors, comment cela peut-il fonctionner?
Rafal
0

Essayez ce qui suit pour remplacer tous les "." Par "."

sed -r 's/\. /\./g' -i sed-dots

Mais pour ". . ." à "..."

sed -r 's/\. \. \./\.\.\./g' -i sed-dots
Meer Borg
la source
0

Je pourrais utiliser votre fichier lorsque je l'ai parcouru:

tr '\240' ' ' < sed-dots.txt > sed-dots.new

Cela a fonctionné sans étape de conversion:

sed 's/[[:blank:]]\.[[:blank:]]\.[[:blank:]]\./.../g' sed-dots.txt
Scrutinisateur
la source
Ça ne marche pas. Je suppose que cette raison est le caractère M-BM étrange que @Oli a trouvé.
Rafal