sed поводиться по-різному на FreeBSD і на Linux?


12

Я використовую і Linux, і FreeBSD (конкретно, я використовую Debian Linux і PC-BSD), і я знайшов щось дивне sed.

Мені часто потрібно конвертувати файли "значень, розділених на вкладку", у "значення, розділені комами". Найпростіший спосіб, який я знаю, - це використовувати sedтакий:

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

Це прекрасно працює в Linux: він замінює кожну вкладку комою ... але на FreeBSD він нічого не замінює !!!

Я щось пропускаю? Чи є синтаксис з FreeBSD, sedякий відрізняється від синхронізації в Linux?

Відповіді:


9

Можливо, вам слід скористатися -Eопцією (або -rяк пояснено в інструкції ), щоб зберегти сумісність з GNU Sed. У вашому випадку ви можете встановити Gnu Sed, якщо ви звикли до нього (порт gsed на FreeBSD), або знадобиться багато часу, щоб перенести скрипти.

І пам’ятайте. Якщо якась команда на BSD не діє як версія gnu цієї утиліти, це не означає, що вона зламана;)


1
Дякую. Ця -Eопція робить хитрість (як на FreeBSD, так і на Mac OS X).
Барранка

У моєму FreeBSD 9 опція -E не допомагає.
Арк-кун

6

Так, існують різні відмінності, поведінка-i - це єдине, кого я знаю, з верхівки голови.

Я ніколи не використовував BSD, тому я не можу реально допомогти з деталями, але trзамість цього може бути використане :

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

Приємним побічним ефектом є те, що trмає бути значно швидше. Я перевірив це на моєму Linux, використовуючи тестовий файл із 50000 рядків, кожен з яких мав 2 вкладки:

$ 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' ,є більш портативним, ніж tr $'\t' ,. tr '[\t]' '[,]'навіть переноситься на деякі старі системи SysV.
Stéphane Chazelas

вкладка - це розділювач за замовчуванням для cut. POSIX специфікації для trце є . Я помилявся про те, що [потрібно для старого SysV. Оскільки ця специфікація POSIX [потрібна лише для діапазонів.
Стефан Шазелас

@StephaneChazelas так, вибачте не впевнений, з чим я його плутаю тоді. Дякуємо за роз’яснення в будь-якому випадку.
terdon

4

Так, на відміну від GNU sedFreeBSD sedне інтерпретує послідовності виходу ANSI C, такі як \tу регулярних виразах.

Одним із способів отримати в цьому випадку найменш поширений знаменник - використовувати printf.

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

Поведінка sed -iредагування файлів на місці може бути сумісною, якщо комутатор або параметр негайно слідує за -iкомутатором, наприклад, sed -i -e 's/x/X/g' fileпрацює як для GNU, sedтак і для FreeBSD sed.

Останні версії FreeBSD sed(FreeBSD 8.1 або новіші) мають -rперемикач для підвищення сумісності з GNU sed.

(Крім того, використання класів символів POSIX у sedрегулярних виразах є хорошим способом забезпечення сумісності також).

Як альтернативу, сумісна з POSIX sedреалізацією див: мінімізована - менша, дешевша, швидша реалізація SED .


3

Ви повинні використовувати буквальний TABсимвол замість \t:

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

Дивіться цей коментар Стефана з іншого питання.

Наступна стаття також може вас зацікавити:

Я цитую відповідну частину:

Відмінності Regex

Синтаксис регулярного вираження помітно відрізняється між різними версіями SED. Більшість відмінностей стосуються спеціальних шаблонів евакуації, які використовуються для узгодження недрукувальних символів, наприклад, дзвінок ASCI та канали форми.


0

Після входу я бачу наступне оголошення і зберігаю його. Сподіваюсь, він буде корисний і для інших

Хочете скористатися sed (1) для редагування файлу на місці? Що ж, щоб замінити кожне 'e' на 'o', у файлі під назвою 'foo', ви можете зробити:

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

І ви отримаєте резервну копію оригіналу у файлі під назвою 'foo.bak', але якщо ви не хочете робити резервну копію:

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

-iваріант був покритий вже , хоча
Джефф Schaller
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.