sed si comporta diversamente su FreeBSD e su Linux?


12

Uso sia Linux che FreeBSD (in particolare, utilizzo Debian Linux e PC-BSD) e ho trovato qualcosa di strano sed.

Ho spesso bisogno di convertire i file "valori separati da tabulazione" in "valori separati da virgola". Il modo più semplice che conosco è usare sed, in questo modo:

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

Funziona perfettamente su Linux: sostituisce ogni scheda con una virgola ... ma su FreeBSD, non sostituisce nulla !!!

Mi sto perdendo qualcosa? Esiste una sintassi con FreeBSD seddiversa da quella su Linux?

Risposte:


9

Forse dovresti usare l' -Eopzione (o -rcome spiegato nel manuale ) per mantenere la compatibilità con GNU Sed. Nel tuo caso, potresti installare Gnu Sed se ci sei abituato (port gsed su FreeBSD), o ci vorrà molto tempo per port script.

E ricorda. Se qualche comando su BSD non si comporta come la versione gnu di quella utility, non significa che sia rotto;)


1
Grazie. L' -Eopzione fa il trucco (sia su FreeBSD che su Mac OS X).
Barranka,

Sul mio FreeBSD 9 l'opzione -E non aiuta.
Ark-kun,

6

Sì, ci sono varie differenze, il comportamento di-i essere l'unico che conosco dalla cima della mia testa.

Non ho mai usato BSD, quindi non posso davvero aiutare con i dettagli, ma una soluzione alternativa potrebbe essere quella di utilizzare trinvece:

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

Un piacevole effetto collaterale è che trdovrebbe essere significativamente più veloce. L'ho provato sul mio Linux usando un file di test con 50000 righe, ognuna delle quali aveva 2 schede:

$ 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' ,è più portatile di tr $'\t' ,. tr '[\t]' '[,]'sarebbe persino portabile su alcuni vecchi sistemi SysV.
Stéphane Chazelas,

tab è il delimitatore predefinito per cut. Le specifiche POSIX per trsono . Avevo torto sul [necessario per il vecchio SysV. Come indica la specifica POSIX, [è necessario solo per gli intervalli lì.
Stéphane Chazelas,

@StephaneChazelas così è, scusa non sono sicuro di cosa lo sto confondendo allora. Grazie per il chiarimento in ogni caso.
terdon

4

Sì, a differenza di GNU sedFreeBSD sednon interpreta sequenze di escape ANSI C come \tnelle espressioni regolari.

Un modo per ottenere un denomiatore meno comune in questo caso è usare printf.

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

Il comportamento delle sed -imodifiche al file sul posto può essere reso compatibile se uno switch o un'opzione seguono immediatamente lo -iswitch, ad esempio sed -i -e 's/x/X/g' filefunziona sia per GNU sedche per FreeBSD sed.

Le versioni recenti di FreeBSD sed(FreeBSD 8.1 o più recenti) hanno il -rpassaggio per aumentare la compatibilità con GNU sed.

(Inoltre, l'uso delle classi di caratteri POSIX nelle sedespressioni regolari è un buon modo per garantire anche la compatibilità).

Per sedun'implementazione alternativa conforme a POSIX vedere: minised - un'implementazione SED più piccola, più economica, più veloce .


3

Dovresti usare un TABcarattere letterale invece di \t:

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

Vedi questo commento di Stephane su un'altra domanda.

Potrebbe interessarti anche il seguente articolo:

Cito la parte pertinente:

Differenze Regex La

sintassi delle espressioni regolari differisce leggermente tra le diverse versioni di SED. La maggior parte delle differenze riguarda speciali modelli di escape utilizzati per abbinare caratteri non stampabili, come la campana ASCI e i feed di moduli.


0

Dopo il login vedo il prossimo annuncio e lo salvo. Spero che sia utile anche per gli altri

Vuoi usare sed (1) per modificare un file in atto? Bene, per sostituire ogni 'e' con una 'o', in un file chiamato 'pippo', puoi fare:

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

E otterrai un backup dell'originale in un file chiamato "foo.bak", ma se non desideri alcun backup:

sed -i '' s/e/o/g foo

l' -iopzione era già coperta , però
Jeff Schaller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.