sed 's/[^ ]* */[&]P/;s//&+pc/3'|dc
... печать ...
2015-01 6000
2015-02 8000
2015-03 10000
Итак, выше я объявляю регулярное выражение, которое определяет экстент поля , состоящий из одной последовательности символов *переменной длины, которые ^не являются <пробелом>, за которыми сразу же следует одна последовательность символов *переменной длины, которые являются <пробелом> . Это объявление применяется к sedпространству паттернов России, которое представляет собой строку, разделенную (по умолчанию) каждым \nсимволом ewline, которая встречается на входе, и которая рекурсивно заменяется (по умолчанию) на следующий для каждого вхождения того же самого.
Интерфейс для этой декларации двоякий, и на каждом уровне он полностью регулируется и определяется по крайней мере одним международным официальным комитетом стандартов IEEE для обеспечения предсказуемого применения sedкомандного синтаксиса. sedСинтаксис API , например, в этом случае применяется с помощью команды /address (которая всегда является первым компонентом любой команды ubstitution) , но его содержимое интерпретируется более базовым API как подмножество, указанное для функция в стандартной библиотеке C ./sed s///regcomp()
Я могу сделать эти заявления уверенно, потому что sedэто не просто программа, а, скорее, скомпилированный исполняемый файл, названный sedна моей Unix-подобной машине, является реализацией четко определенного, исторически сложившегося и управляемого стандартами sed приложения моей системы. библиотеки соответствия выражений.
Из sedспецификации:
sedУтилита должна поддерживать Brès , описанный в XBD основных регулярных выражений ...
... где мы находим ...
Оба Brès и EREs поддерживаются Regular Expression Matching интерфейс в объеме системы Интерфейсы POSIX.1-2008 под regcomp(), regexec()и функции , связанные.
Приложение, которое вызывает regcomp(), представит ему строку шаблона и ...
... [t] regcomp()Функция he должна скомпилировать регулярное выражение, содержащееся в строке, на которую указывает аргумент шаблона, и поместить результаты в структуру preg ...
Чтобы действовать в этом направлении, указанное приложение будет ссылаться на regcomp()сопутствующую функцию ...
... [t] regexec()Функция he сравнивает строку с нулем в конце, указанную в строке, с скомпилированным регулярным выражением preg, инициализированным предыдущим вызовом regcomp()...
... regexec()заполняет элементы [с] массивом с смещениями подстрок строки , которые соответствуют в \(скобках подвыражения \)из шаблона ... узора сам по себе считается подвыражениями ...
... [t] regexec()функция должна заполнять все элементы nmatch в pmatch , где nmatch и pmatch предоставляются приложением, даже если некоторые элементы pmatch не соответствуют подвыражениям в шаблоне .
И так, когда я делаю ...
/[^ ]* */
... sedсначала компилирует регулярное выражение и сохраняет результаты в памяти, а затем применяет скомпилированный автомат, хранящийся там, к содержимому моего пространства шаблонов столько раз, сколько необходимо для выполнения моей команды. Каждый раз, когда это происходит, результатом является массив из одного или более полей с нулевым разделением, которые разграничиваются смещениями, возвращаемыми regexec().
И когда я делаю ...
//
... чтобы указать, что следует использовать последнее определенное регулярное выражение, sedможно просто regexec()снова вызвать повторно скомпилированное регулярное выражение, но, возможно, применить его на этот раз к измененному строковому аргументу или применить новые параметры nmatch в качестве команды I.
Точнее еще ...
s/[^ ]* */[&]P/
- замените первое вхождение pattern в pattern-space на
[левую квадратную скобку, затем на &себя, затем на ]правую квадратную скобку, за которой следует Pсимвол.
s//&+pc/3
- примените последнее использованное регулярное выражение снова к текущему пространству шаблона и замените
3третье вхождение шаблона в пространстве шаблона на &себя, за которым следует добавленная строка +pc.
И поэтому для каждой строки sedввода он записывает в свой стандартный вывод, учитывая данные вашего примера:
[2015-01 ]P5000 1000+pc
[2015-02 ]P6000 2000+pc
[2015-03 ]P7000 3000+pc
Это может показаться странным, но dcкалькулятор заключает в кавычки строки в своих входных данных в квадратных скобках, и Pкоманда будет печатать верхнюю часть стека без добавления \newline, а затем выталкивать его из стека ввода.
И так, используя первую строку там в качестве примера, dcсделаем:
[2015-01 ]P
Pнабросать и вытолкнуть вершину стека
5000
- Вставьте число
5000в верхнюю часть стека и сдвиньте все элементы, находящиеся в данный момент в стеке (теперь их нет) , на единицу.
1000
- То же самое, но на этот раз число 5000 в верхней части основного стека уменьшается на единицу и становится вторым элементом в стеке.
+
- Сложите два верхних числа в стеке, вытяните оба из стека и поместите сумму в верхнюю часть стека.
- В результате получается стек, состоящий только из числа
6000.
- Это синтаксическая ошибка, если любой из двух верхних элементов в стеке является
[строкой ].
p
pОтпечатайте вершину стека, а затем добавленную \newline, не выталкивая ее из стека.
c