sed zachowuje się inaczej na FreeBSD i na Linuksie?

12

Używam zarówno Linuksa, jak i FreeBSD (konkretnie używam Debiana Linux i PC-BSD) i znalazłem coś dziwnego sed.

Często muszę konwertować pliki „wartości rozdzielane tabulatorami” na „wartości rozdzielane przecinkami”. Najprostszym sposobem, jaki znam, jest sednastępujący:

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

Działa to doskonale w systemie Linux: zastępuje każdą kartę przecinkiem ... ale w FreeBSD nic nie zastępuje !!!

Czy coś brakuje? Czy istnieje składnia z FreeBSD sedinna niż ta w Linuksie?

Barranka
źródło

Odpowiedzi:

9

Może powinieneś skorzystać z -Eopcji (lub -rjak wyjaśniono w instrukcji ), aby zachować zgodność z GNU Sed. W twoim przypadku możesz zainstalować Gnu Sed, jeśli jesteś do niego przyzwyczajony (port gsed na FreeBSD), lub zajmie to dużo wysiłku, aby przenieść skrypty.

I pamiętaj. Jeśli jakieś polecenie na BSD nie działa jak wersja GNU tego narzędzia, to nie znaczy, że jest zepsute;)


źródło
1
Dziękuję Ci. Ta -Eopcja stanowi trick (zarówno na FreeBSD, jak i Mac OS X).
Barranka
W moim FreeBSD 9 opcja -E nie pomaga.
Ark-kun
6

Tak, istnieją różne różnice, zachowanie-i jest jedynym znanym mi z głowy.

Nigdy nie korzystałem z BSD, więc nie mogę naprawdę pomóc w szczegółach, ale trzamiast tego można zastosować obejście :

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

Przyjemny efekt uboczny trpowinien być znacznie szybszy. Przetestowałem to na moim systemie Linux, używając pliku testowego z 50000 liniami, z których każda miała 2 zakładki:

$ 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
źródło
tr '\t' ,jest bardziej przenośny niż tr $'\t' ,. tr '[\t]' '[,]'byłby nawet przenośny na niektóre stare systemy SysV.
Stéphane Chazelas
tab jest domyślnym ogranicznikiem dla cut. POSIX spec trjest tam . Myliłem się co do [potrzeb dla starego SysV. Jak wskazuje ta specyfikacja POSIX, [jest ona potrzebna tylko dla tam dostępnych zakresów.
Stéphane Chazelas
@StephaneChazelas, więc jest, przepraszam, nie jestem pewien, z czym to mylę. Dzięki za wyjaśnienie w każdym przypadku.
terdon
4

Tak, w przeciwieństwie do GNU sedFreeBSD sednie interpretuje sekwencji specjalnych ANSI C, takich jak \twyrażenia regularne.

Jednym ze sposobów na uzyskanie najmniej popularnego denomiatora w tym przypadku jest użycie printf.

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

Zachowanie sed -iedycji plików w miejscu może być kompatybilne, jeśli przełącznik lub opcja bezpośrednio następuje po -iprzełączniku, np. sed -i -e 's/x/X/g' fileDziała zarówno dla GNU, sedjak i FreeBSD sed.

Najnowsze wersje FreeBSD sed(FreeBSD 8.1 lub nowsze) mają -rprzełącznik zwiększający kompatybilność z GNU sed.

(Ponadto użycie klas znaków POSIX w sedwyrażeniach regularnych jest dobrym sposobem na zapewnienie zgodności).

Alternatywna sedimplementacja zgodna z POSIX patrz: minised - mniejsza, tańsza, szybsza implementacja SED .

kroy
źródło
3

Powinieneś użyć dosłownego TABznaku zamiast \t:

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

Zobacz ten komentarz Stephane'a na inne pytanie.

Poniższy artykuł może Cię również zainteresować:

Cytuję odpowiednią część:

Różnice

wyrażeń regularnych Składnia wyrażeń regularnych różni się nieznacznie między różnymi wersjami SED. Większość różnic dotyczy specjalnych wzorów zmiany znaczenia używanych do dopasowania znaków, które nie są drukowane, takich jak dzwonek ASCI i formularze.

Joseph R.
źródło
0

Po zalogowaniu widzę następne ogłoszenie i zapisuję je. Mam nadzieję, że przyda się także innym

Chcesz użyć sed (1) do edycji pliku na miejscu? Cóż, aby zamienić każde „e” na „o”, w pliku o nazwie „foo” możesz:

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

Otrzymasz kopię zapasową oryginału w pliku o nazwie „foo.bak”, ale jeśli nie chcesz kopii zapasowej:

sed -i '' s/e/o/g foo
TradeNarK
źródło
-iopcja została pokryta już , choć
Jeff Schaller