sed
API API примітивний - і це задумом. Принаймні, він залишився примітивним по дизайну - чи був він створений примітивно на початку, я не можу сказати. У більшості випадків написання sed
сценарію, який при запуску видасть інший sed
сценарій , справді є простою справою. sed
дуже часто застосовується таким чином макропроцесорами, такими як m4
та / або make
.
(Далі - це дуже гіпотетичний випадок використання: це проблема, розроблена для рішення рішення. Якщо вам це здається розтягнутим, то це, мабуть, тому, що воно є, але це не обов'язково робить його менш вагомим.)
Розглянемо наступний вхідний файл:
cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower
Якби ми хотіли написати sed
сценарій, який додав би слово -case до хвоста кожного відповідного слова у наведеному вище вхідному файлі, лише якщо його можна було знайти у рядку у відповідному контексті , і ми хотіли зробити це максимально ефективно ( як це повинно бути нашою метою, наприклад, під час операції компіляції), тоді ми повинні віддавати перевагу максимально уникати застосування /
regexp /
s.
Одне, що ми можемо зробити - це попередньо відредагувати файл у нашій системі прямо зараз, і ніколи не дзвонити sed
під час компіляції. Але якщо будь-яке з цих слів у файлі має або не повинно бути включене на основі локальних налаштувань та / або варіантів часу компіляції, то це, ймовірно, не буде бажаною альтернативою.
Ще одна річ, яку ми можемо зробити, це обробити файл тепер проти regexps. Ми можемо створити - і включити до нашої компіляції - sed
сценарій, який може застосовувати правки відповідно до номера рядка - що, як правило, набагато ефективніший маршрут у довгостроковій перспективі.
Наприклад:
n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed " 1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
s/ *cat/!/g;s/ *dog/!/g
s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'
... який записує вихід у вигляді sed
сценарію і виглядає як ...
#!/usr/heirloom/bin/posix2001/sed -nf
:1
1!n;1!b1
1s/.*/camel-case/p
:2
2!n;2!b2
2!!s/.*/camel-case/p
:5
5!n;5!b5
5s/.*/upper-case/p
:6
6!n;6!b6
6s/.*/lower-case/p
q
Коли цей вихід зберігається у виконавчому текстовому файлі на моїй машині, який називається ./bang.sed
та працює як ./bang.sed ./infile
, вихід:
camel-case
upper-case
lower-case
Тепер ви можете запитати мене ... Чому я хотів би це зробити? Чому б я не просто якір grep
матчів? Хто все-таки використовує футляр з верблюдами? І на кожне запитання я міг відповісти лише, я поняття не маю ... тому що не знаю. Перш ніж прочитати це питання, я ніколи особисто не помічав мульти-! вимога розбору в специфікації - я думаю, що це досить акуратний вилов.
Мульти-! щось одразу мало сенс для мене, хоча значна частина sed
специфікації орієнтована на просто проаналізований та просто створений sed
сценарій. Ви, ймовірно, знайдете необхідні \n
роздільники ewline, щоб [wr:bt{]
зробити в цьому контексті набагато більше сенсу, і якщо ви пам’ятаєте про цю ідею, ви можете краще зрозуміти деякі інші аспекти специфікації - (наприклад, :
не приймаючи адреси та q
відмовляючись від прийміть більше 1) .
У наведеному вище прикладі я виписати певну форму sed
скрипт , який може тільки коли - небудь буде читати один раз. Якщо ви дуже важко подивитесь на це, ви можете помітити, що, sed
читаючи файл редагування, він переходить від одного командного блоку до іншого - він ніколи не відганяється від або не завершує редагування сценарію до повного завершення редагувального файлу.
Я вважаю це багато-! адреси можуть бути кориснішими в цьому контексті, ніж у деяких інших, але, чесно кажучи, я не можу придумати жодного випадку, в якому я міг би використати це дуже добре - і я sed
дуже багато. Я також вважаю, що примітним є те, sed
що обидва GNU / BSD не справляються з цим, як зазначено - це, мабуть, не аспект специфікації, який користується великим попитом, і тому, якщо реалізація проглядає це, я сумніваюся дуже серйозно, їх помилки @ box постраждають в результаті жахливо.
Однак, невдача з цим завданням є помилкою для будь-якої реалізації, яка претендує на відповідність, і тому я думаю, що для цього потрібно запустити електронний лист у відповідні поля розробників, і я маю намір це зробити, якщо ви цього не зробите.
!
діє як перемикач,/pattern/!!
те саме/pattern/
, що і/pattern/!!!
, як/pattern/!
. У FreeBSD множини!
такі ж, як і одні.