sed se comporta de maneira diferente no FreeBSD e no Linux?

12

Eu uso o Linux e o FreeBSD (especificamente, o Debian Linux e o PC-BSD), e achei algo estranho sed.

Frequentemente, preciso converter arquivos "valores separados por tabulação" em "valores separados por vírgula". A maneira mais simples que eu sei é usar sed, assim:

sed 's/\t/,/g' inputFile.txt > outputFile.csv

Isso funciona perfeitamente no Linux: ele substitui todas as guias por vírgula ... mas no FreeBSD, não substitui nada !!!

Estou esquecendo de algo? Existe uma sintaxe no FreeBSD seddiferente da do Linux?

Barranka
fonte

Respostas:

9

Talvez você deva usar a -Eopção (ou -rconforme explicado no manual ) para manter a compatibilidade com o GNU Sed. No seu caso, você pode instalar o Gnu Sed se estiver acostumado (porta gsed no FreeBSD), ou será necessário um longo esforço para portar scripts.

E lembre-se. Se algum comando no BSD não funciona como a versão gnu desse utilitário, isso não significa que está quebrado;)


fonte
1
Obrigado. A -Eopção faz o truque (no FreeBSD e no Mac OS X).
Barranka 28/11
No meu FreeBSD 9, a opção -E não ajuda.
Arca-kun
6

Sim, existem várias diferenças, o comportamento de-i ser o único que eu conheço do topo da minha cabeça.

Eu nunca usei o BSD, então não posso ajudar com os detalhes, mas uma solução alternativa pode ser usar tr:

tr '\t' , < inputFile.txt > outputFile.csv

Um efeito colateral agradável é que trdeve ser significativamente mais rápido. Eu testei isso no meu Linux usando um arquivo de teste com 50000 linhas, cada uma das quais com 2 guias:

$ time tr '\t' , < foo.txt > /dev/null 

real    0m0.004s
user    0m0.000s
sys     0m0.000s

$ time sed 's/\t/,/g' foo.txt > /dev/null 

real    0m0.039s
user    0m0.036s
sys     0m0.000s
terdon
fonte
tr '\t' ,é mais portátil que tr $'\t' ,. tr '[\t]' '[,]'seria portátil para alguns sistemas SysV antigos.
Stéphane Chazelas
tab é o delimitador padrão para cut. A especificação POSIX para trestá . Eu estava errado sobre o [necessário para o antigo SysV. Como as especificações do POSIX apontam, [é necessário apenas para os intervalos lá.
Stéphane Chazelas
@StephaneChazelas assim é, desculpe, não sei o que estou confundindo com isso então. Obrigado pelo esclarecimento em qualquer caso.
terdon
4

Sim, ao contrário do GNU sedFreeBSD sednão interpreta seqüências de escape ANSI C, como \tem expressões regulares.

Uma maneira de obter um denominador menos comum nesse caso é usar printf.

tab="$(printf '\t')"
printf '\t\n' | sed 's/'"${tab}"'/,/g'
printf '\t\n' | sed 's/'"$(printf '\t')"'/,/g'

O comportamento das sed -iedições de arquivo no local pode ser compatível se uma opção ou opção seguir imediatamente a -iopção, por exemplo, sed -i -e 's/x/X/g' filefunciona tanto para o GNU sedquanto para o FreeBSD sed.

Versões recentes do FreeBSD sed(FreeBSD 8.1 ou mais recente) têm a -ropção de aumentar a compatibilidade com o GNU sed.

(Além disso, o uso de classes de caracteres POSIX em sedexpressões regulares também é uma boa maneira de garantir compatibilidade).

Para uma alternativa, sedimplementação compatível com POSIX, consulte: minised - uma implementação SED menor, mais barata e mais rápida .

kroy
fonte
3

Você deve usar um TABcaractere literal em vez de \t:

sed 's/    /,/g' inputFile.txt > outputFile.csv

Veja este comentário de Stephane em outra pergunta.

O seguinte artigo também pode lhe interessar:

Cito a parte relevante:

Diferenças de Regex

A sintaxe da expressão regular difere sutilmente entre as diferentes versões do SED. A maioria das diferenças envolve padrões de escape especiais usados ​​para corresponder caracteres não imprimíveis, como a campainha ASCI e os feeds de formulário.

Joseph R.
fonte
0

Após o login, vejo o próximo anúncio e o salvo. Espero que seja útil para outros também

Deseja usar o sed (1) para editar um arquivo no local? Bem, para substituir cada 'e' por um 'o', em um arquivo chamado 'foo', você pode:

sed -i.bak s/e/o/g foo

E você obterá um backup do original em um arquivo chamado 'foo.bak', mas se você não quiser fazer backup:

sed -i '' s/e/o/g foo
TradeNarK
fonte
a -iopção estava coberta , porém
Jeff Schaller