Имеется выхлоп dpkg -l вида:
ii  2048-qt                                                     0.1.6-2+b2                                   amd64        mathematics based puzzle game
ii  aapt                                                        1:8.1.0+r23-3+b2                             amd64        Android Asset Packaging Tool
ii  abiword                                                     3.0.4~dfsg-2                                 amd64        efficient, featureful word processor with collaboration
ii  abiword-common                                              3.0.4~dfsg-2                                 all          efficient, featureful word processor with collaboration -- common files
ii  accountsservice                                             0.6.55-3                                     amd64        query and manipulate user account information
(гусары с aptitude и прочими готовыми колясками — молчать! Задача учебная!)
Надо выгрепнуть из него все строчки пакетов, у которых статус — установлен. То есть в первой колонке есть буковка i. Дело осложняется тем, что кроме ii, там может быть hi, ic, it и прочая шняга.
Решение однострочником, сложное и неудобное:
dpkg -l|grep -P '^[^\s]*?i[^\s]*?\s'
Уже видно, что регулярка страшная. А если не по первой колонке грепать, а по какой-нибудь пятой, то станет ещё страшнее и непонятнее. Плюс нужен расширенный синтаксис grep, который не во всех реализациях grep присутствует, а потому юзать его — фу!
Куда проще сделать:
dpkg -l|col1|grep i
, не так ли? ;)
(здесь col1..col9 — мини-скриптик из пакета byobu, который является, грубо говоря, просто удобным алиасом для awk '{print $1}')
Очевидная проблема здесь, однако же, в том, что в конвейере теряется важная информация, а именно вся строчка, которую нужно отобразить! Остаётся только огрызок в виде первой колонки!
Как решить эту задачу в один конвейер и красиво? А никак :P
Привлекаем императивный язык с промежуточными переменными!
import sys
for line in sys.stdin.readlines():
    if 'i' in line.split()[0]:
        sys.stdout.write(line)
Но всё равно некрасиво, линейный код с искусственным ветвлением через переменную. Вот бы запрограммировать двумерно! Как-то так:
        +-----+ colstream  +-----+  +------+ bool
line-+->| ||| >===========>| [1] >->| Y  i >--------+
     |  +-----+            +-----+  +------+        | transistor
     |                           +->/dev/null     --+--
     +-------------------------------------------/     \->-------> output
(где Y — пиктограмма воронки, как в Excel ;))
Этим и отличается текстовое программирование от графического: текстовое — одномерное, графическое — двумерное! В порог человеческого восприятия ещё и трёхмерное влезет; до такого вроде ещё не додумались (ну, если Minecraft’овский Redstone и аналоги не считать), но у Нас мыслишки есть ;)
Интересно, как реализуют эту задачу Их Метапрожейшество 
metaprog ;) В отличие от тех «простых» задачек, что обычно предлагают в метапроготредах, эта займёт всего пару минут Вашего драгоценного метавремени, не так ли? ;) И послужит хорошей демонстрацией в копилочку того, чем хорош Метапрог (если он, конечно, хорош).
Антиметапрогеры превентивно посылаются в высирач, но могут предложить свои варианты конвейерной (не некрасивой императивной) обработки на текстовых ЯП, ибо почему бы и нет. Латентные (и не только!) шиндузятники с пошуршеллом тоже приветствуются, ага.


