Cela devrait être vraiment simple, mais pour une raison quelconque, cela ne fonctionne pas:
sed -i.bak -E 's/\t/ /' file.txt
Au lieu de remplacer les caractères de tabulation, il remplace les caractères t
. J'ai essayé toutes les variantes auxquelles je pouvais penser, en jouant avec les citations, etc. J'ai recherché sur Google et trouvé tout le monde en utilisant des expressions assez similaires et elles semblent fonctionner pour elles.
Le -E
est une chose OS X. Je pensais que l'échec pourrait être le résultat d'une bizarrerie bizarre du sed
d'OS X, alors je l'ai essayé avec Ruby également (sans le -i
), et a obtenu le même résultat:
Ruby -pe '$_.gsub!(/\t/," ")' < file.txt > file.new
J'utilise Bash 3.2.51 sur OS X et iTerm, bien que je ne vois pas comment ces éléments pourraient être terriblement pertinents. Je n'ai pas défini de variables d'environnement étranges, bien que je puisse poster celles que vous pensez être pertinentes.
Qu'est-ce qui pourrait mal?
[~ # ~] update [~ # ~]: J'ai dû faire une autre erreur ou faute de frappe quand j'ai essayé la version Ruby, car Gilles souligne que cela le fait fonctionne (et j'ai jamais lui a fait me diriger faux!). Je ne suis pas sûr de ce qui s'est passé, mais je suis presque sûr que ce doit être mon erreur.
La syntaxe \t
pour un caractère de tabulation dans sed n'est pas standard. Cette fuite est un extension GNU sed . Vous trouverez de nombreux exemples en ligne qui l'utilisent parce que beaucoup de gens utilisent GNU sed (c'est l'implémentation sed sur Linux non embarqué). Mais OS X sed , comme les autres * BSD sed, ne prend pas en charge \t
pour l'onglet et traite à la place \t
comme une barre oblique inverse suivie de t
.
Il existe de nombreuses solutions, telles que:
Utilisez un caractère de tabulation littéral.
sed -i.bak 's/ / /' file.txt
Utilisez tr
ou printf
pour produire un caractère de tabulation.
sed -i.bak "s/$(printf '\t')/ /" file.txt
sed -i.bak "s/$(echo a | tr 'a' '\t')/ /" file.txt
Utilisez bash's syntaxe de chaîne permettant les échappements antislash .
sed -i.bak $'s/\t/ /' file.txt
Utilisez Perl, Python ou Ruby. L'extrait Ruby que vous avez publié fonctionne).
Utilisez un Bash spécifique entre guillemets qui vous permet d'utiliser des chaînes comme en C, de sorte qu'un vrai caractère de tabulation soit passé à sed, pas une séquence d'échappement:
sed -i.bak -E $'s/\t/ /' file.txt
sed -i $'s/\t/ /g' file.txt
fonctionne pour moi sur OS X et est la même commande que j'utilise sur linux tout le temps.
Comme indiqué, toutes les implémentations de sed
ne prennent pas en charge la notation de \t
en tant qu'onglet horizontal.
Vous pouvez facilement réaliser votre substitution avec:
Perl -pi.old -e 's{\t+}{ }g' file.txt
Cela effectue un remplacement in situ qui préserve votre fichier d'origine en tant que "* .old". Perl permet des délimiteurs alternatifs pour le classique /
rendant l'expression beaucoup plus lisible (c'est-à-dire dépourvue du syndrome du "cure-dent penchée").
Le +
indique qu'une ou plusieurs répétitions d'un caractère de tabulation doivent être remplacées. Le modificateur g
permet des remplacements globaux jusqu'à la fin de chaque ligne.
S'il est correct d'exiger bash
ou zsh
en tant que shell, alors c'est la solution la plus simple à laquelle je peux penser:
sed "s/$(echo -n -e "\t")/ /" file.txt
Notez cependant que echo
drapeaux (-n
et -e
) ne sont pas définis dans POSIX, donc un Shell conforme POSIX n'a pas besoin de comprendre ces drapeaux, mais beaucoup le seront pour des raisons de compatibilité.
Vous pouvez également utiliser echo
dans sed
:
sed -i "s/$(echo '\t')//g"
Si vous voulez un sed
plus puissant (supportant \t
et plus) que celui sous OS X, installez GNU sed .