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?

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;)


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

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 .


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.


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

a -iopção estava coberta , porém
Jeff Schaller
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.