Isso deve ser muito simples, mas por algum motivo não está funcionando:
sed -i.bak -E 's/\t/ /' file.txt
Em vez de substituir caracteres de tabulação, está substituindo t
caracteres. Eu tentei todas as variações que pude pensar, brincando com citações, etc. Pesquisei no Google e encontrei todo mundo usando expressões muito semelhantes e elas parecem funcionar para elas.
O -E
é uma coisa do OS X. Eu pensei que a falha poderia ser o resultado de alguma peculiaridade estranha do OS X sed
, então eu tentei com o Ruby também (sem o -i
) e obtive o mesmo resultado:
ruby -pe '$_.gsub!(/\t/," ")' < file.txt > file.new
Estou usando o Bash 3.2.51 no OS X e no iTerm, embora não consiga ver como isso poderia ser terrivelmente relevante. Eu não defini nenhuma variável de ambiente estranha, embora eu possa postar alguma que você ache relevante.
O que pode estar errado?
ATUALIZAÇÃO : Devo ter feito algum outro erro ou erro de digitação quando eu tentei a versão Ruby, desde Gilles salienta que faz o trabalho (e eu já não tinha ele me orientar errado!). Não tenho certeza do que aconteceu, mas tenho certeza de que deve ter sido meu erro.
fonte
\t
nased
instrução porCTRL-V<TAB>
onde<TAB>
está a tecla Tab e aCTRL-V
tecla Control ev
pressionadas juntas.Respostas:
A sintaxe
\t
para um caractere de tabulação no sed não é padrão. Essa fuga é uma extensão GNU sed . Você encontra muitos exemplos on-line que o usam porque muitas pessoas usam o GNU sed (é a implementação sed no Linux não incorporado). Mas o OS X sed , como outro * BSD sed, não suporta\t
tab e, em vez disso, trata\t
como significando barra invertida seguida port
.Existem muitas soluções, como:
Use um caractere de tabulação literal.
Use
tr
ouprintf
para produzir um caractere de tabulação.Use a sintaxe de string do bash, permitindo escapes de barra invertida .
Use Perl, Python ou Ruby. O snippet de Ruby que você postou funciona.
fonte
...sed
script (usado via-f
opção), os caracteres da guia literal parecem a única possibilidade para mim. Ao editar isso com o vim,set noexpandtab
é importante.tr
técnica somente se você quiser que seu colega de trabalho lhe apunhale quando ele ler seu script.sed $'s/<regex>/\t/' file.txt
funciona para inserir, mas$
parece quebrar meu script quando tento incluir parte do regex na minha substituição, ou seja,sed $'s,\(ontology/[0-9]\+\),\t\txxx\1xxx\t\t,'
dá `xxxxxx` com o meu valor de correspondência esperado substituído por ``. Existe um equivalente ao\1
usar a sintaxe de string do bash? Edit: é suposto o caractere unicode U + 231C no meio do xxx <U + 231C> xxx.Use uma citação específica do Bash que permita usar seqüências de caracteres como em C, para que um caractere de tabulação real seja passado para sed, não uma sequência de escape:
fonte
funciona para mim no OS X e é o mesmo comando que eu uso no linux o tempo todo.
fonte
Como observado, nem todas as
sed
implementações suportam a notação\t
como uma guia horizontal.Você pode facilmente conseguir sua substituição com:
Isso realiza uma substituição in situ que preserva o arquivo original como "* .old". O Perl permite delimitadores alternativos para o clássico,
/
tornando a expressão muito mais legível (ou seja, desprovida da síndrome do "palito de dentes inclinado").O
+
diz um ou mais repetições de um caractere de tabulação devem ser substituídos. Og
modificador permite substituições globais no final de cada linha.fonte
Você também pode usar
echo
dentrosed
:sed -i "s/$(echo '\t')//g"
fonte
echo '\t'
apenas produzirá\t
na implementação de alguns shells deecho
.Se você quer um mais poderoso
sed
(suportado\t
e mais) do que o OS X, instale o GNU sed .fonte
sed
o problema do OS X é. Você tem um motivo para acreditar que esse é o problema? Eu ficaria feliz em instalar o GNU sed se tivesse motivos para acreditar que resolveria o problema, mas parece que eu já descartei isso.ruby -pe '$_.gsub!(/\t/," ")' < file.txt
Se não há problema em exigir
bash
ouzsh
como um shell, então esta é a solução mais fácil que consigo pensar:Observe, no entanto, que os
echo
sinalizadores (-n
e-e
) são indefinidos no POSIX, portanto, um shell em conformidade com o POSIX não requer a compreensão desses sinalizadores, mas muitos o farão por motivos de compatibilidade.fonte
Estou surpreso que ninguém tenha sugerido a solução muito simples de:
sed -i.bak -E 's/\\\t/ /' file.txt
Isso deve funcionar.Você precisa escapar da fuga (daí os 3 \ s) para permitir ao sed entender que você está tentando usar um caractere \ t na expressão regular quando tudo é substituído ...
fonte
sed
,\
basta um, pois não é necessário escapar. O problema é que o BSDsed
não suporta essa sintaxe para guias.Isso funcionou para mim.
sed -e 's / [\ t] / / g'
fonte
sed
. Não é isso que o OP usa.