Какие общие советы у вас есть для игры в гольф в седе? Я ищу идеи, которые могут быть применены к задачам кода-гольфа и которые, по крайней мере, несколько специфичны для sed (например, «удалить комментарии» - это не ответ).
Пожалуйста, оставьте один совет за ответ.
F
команда никогда не работала. Кто-нибудь знает почему?F
работает над моим GNU sed (тестирование Debian). Конечно, он печатает только-
при чтении со стандартного ввода, но это ожидаемо. Что вы получаете отsed -e 'F;Q' /etc/hostname
?char 1: unknown command: F
. Возможно, мне нужно обновить sed; какая у вас версия? КомандаL
также не работает, но в любом случае она бесполезна, поскольку-l n
существует. Все остальное упомянутое на сайте GNU sed работает.bash, sed and dc
для всех, кто хочет поговорить и спросить об этих языках. Давайте сделаем сообщество!Ответы:
Если вам нужно использовать ярлыки , вы наверняка захотите, чтобы названия ваших ярлыков были как можно короче. Фактически, вы можете использовать пустую строку в качестве имени метки:
источник
:
теперь требует ярлык.Документация по GNU sed описывает
s
команду как «Швейцарский армейский нож sed» . Но если все, что вы хотите сделать, это заменить все экземпляры одного символа другим,y
то вам нужна команда:один символ короче чем:
источник
y/12/21/
Попробуйте использовать расширенный синтаксис регулярных выражений (в GNU sed).
-r
Вариант стоит один байт в выигрыше, но использовать его только один раз , чтобы исключить обратный слэш из пары\(...\)
уже заплатил за себя.источник
-r
кажетсяsed
специфичным для GNU .+
,?
,{}
и|
в регулярном выражении соответствует, так как нет обратных слэша не требуется ни.-E
работает как псевдоним-r
во многихsed
реализациях, если я правильно помню.При многократной замене в цикле:
обычно нет необходимости заменять глобально, поскольку цикл в конечном итоге заменит все вхождения:
Обратите также внимание на расширение GNU, приведенное выше: метка может иметь пустое имя, сохраняя больше ценных байтов. В других реализациях метка не может быть пустой, и переход без метки передает поток в конец скрипта (т.е. так же, как
n
).источник
:
)Там нет встроенной арифметики, но вычисления могут быть сделаны в одинарном или в десятичном формате. Следующий код преобразует десятичное число в UCD с x в качестве единицы и 0 в качестве разделителя цифр:
и вот преобразование обратно в десятичное:
Оба они взяты из ответа на «Умножение двух чисел без использования каких-либо чисел» .
Обычный старый унар может быть преобразован с помощью этой пары циклов из этого ответа в "{Curly Numbers};" где блок находится
;
. Я использовалv
иx
чтобы соответствовать Роман для5
и10
;b
происходит от "бис".источник
/[;v]/!s/\b/0/2
, которую необходимо изменить, чтобы/[;v]/!s:x\+:&0:
она работала. Смотрите здесь .Как упоминалось в
man sed
(GNU), вы можете использовать любой символ в качестве разделителя для регулярных выражений, используя синтаксисгде
%
заполнитель для любого персонажа.Это полезно для таких команд, как
которые короче как
То, что упомянуто в руководстве GNU sed, но не в
man sed
том, что вы можете изменить разделителиs///
иy///
.Например, команда
удаляет все косые черты из пространства шаблона.
источник
Если этот вопрос явно не запрещен, консенсус по этому мета-вопросу заключается в том, что числовой ввод может быть одинарным. Это экономит вам 86 байтов от десятичного до унарного согласно этому ответу .
источник
В продолжение этого ответа на вопрос о преобразованиях десятичных и простых унарных числовых форматов я представляю следующие альтернативные методы с их преимуществами и недостатками.
От десятичного до простого унарного: 102 + 1 (флаг r) = 103 байта. Я считал
\t
буквальную вкладку, как 1 байт.Попробуйте онлайн!
Преимущество: он на 22 байта короче и, как дополнительный, работает с отрицательными целыми числами в качестве входных данных
Недостаток: перезаписывает пространство удержания. Однако, поскольку более вероятно, что вам нужно преобразовать входное целое число в самом начале программы, это ограничение ощущается редко.
От простого числа к десятичному: 102 + 1 (флаг r) = 103 байта
Попробуйте онлайн!
Преимущество: это на 14 байтов короче. На этот раз обе подсказки работают для отрицательных целых чисел в качестве входных данных.
Недостаток: перезаписывает пространство удержания
Для сложной задачи вам придется адаптировать эти фрагменты для работы с другой информацией, которая может существовать в пространстве шаблона или в пространстве хранения, помимо числа для преобразования. Код может быть более точным, если вы знаете, что работаете только с положительными числами или только один ноль не будет правильным вводом / выводом.
Примером такого сложного ответа, где я создал и использовал эти фрагменты, является Взаимное число (1 / x) .
источник
s:\n|@$::g
. tio.run/##K05N@f@/2ErX3krNwIpL30G/…-r
, но с новым консенсусом флаги в любом случае не учитываются в счет байтаунта , и это не/\n/ta
на/\n/t
, вы сохраните 1 байт, чтобы получить 96Давайте поговорим о том
t
иT
командах, что , хотя они описаны в справочной странице, можно легко забыть об этом и ввести ошибки случайно, особенно , когда код становится сложным.Справочная страница для
t
:Пример, показывающий, что я имею в виду: допустим, у вас есть список чисел, и вы хотите подсчитать, сколько существует негативов. Частичный код ниже:
Выглядит хорошо, но это не так. Если первое число положительное, этот код все равно будет считать его отрицательным, поскольку переход, выполненный
t
для первой строки ввода, выполняется независимо от того, что произошла успешнаяs
замена при инициализации счетчика! Правильно это:/-/b increment_counter
.Если это кажется легким, вы все равно можете быть одурачены при выполнении нескольких прыжков назад и вперед для имитации функций. В нашем примере
increment_counter
блок кода наверняка будет использовать многоs
команд. Возвращение назадb main
может привести к тому, что другая проверка в «main» попадет в ту же ловушку. Вот почему я обычно возвращаюсь из блоков кода сs/.*/&/;t label
. Это некрасиво, но полезно.источник
Вместо очистки пространства шаблона с
s/.*//
помощьюz
команды (в нижнем регистре), если вы используете GNU sed. Помимо меньшего числа байтов, он имеет то преимущество, что не запускает следующий цикл, как этоd
делает команда , что может быть полезно в определенных ситуациях.источник
.
).Я знаю, что это старый поток, но я только что нашел эти неуклюжие преобразователи десятичных чисел в UCD, с почти сотней байтов, некоторые даже запутывают пространство удержания или требуют специальных ошибочных
sed
версий.Для десятичного в UCD я использую (68 байт; первый лучше всего размещен здесь 87 байт)
UCD в десятичном формате (также 66 байтов; первый лучше всего размещен здесь 96)
\n
в замене не портативно. Вместо этого вы можете использовать другой символ и сохранить два байта, но вам потребуется больше байтов для удаления приложения вместоP;d
; см. следующее замечание Или, если ваше пространство удержания пусто, обойтисьG;s/$/9876543210/
без байтового штрафа.s/\n.*//
вместоP;d
.sed
версий GNU с ошибкамиисточник
sed
версиями, которые нарушают стандарт POSIX.Прочитайте весь ввод сразу с
-z
Часто вам нужно работать со всем вводом сразу, а не по одной строке за раз. Команда
N
полезна для этого:... но обычно вы можете пропустить это и использовать
-z
вместо этого флаг.-z
Флаг делает SED использования NUL (\0
) в качестве входной строки разделителя вместо\n
, так что если вы знаете , что ваш вход не будет содержать\0
, он будет читать весь вход сразу в качестве одной «линии»:Попробуйте онлайн!
источник
Добавить новую строку одним байтом
Команда
G
добавляет новую строку и содержимое пространства удержания в пространство образца, так что если ваше пространство удержания пусто, вместо этого:Ты можешь сделать это:
Добавить новую строку в три байта
Команда
H
добавляет новую строку и содержимое пространства шаблона в пространство удержания иx
меняет их местами, так что если ваше пространство удержания пусто, вместо этого:Ты можешь сделать это:
Это приведет к загрязнению вашего трюма, поэтому работает только один раз. Однако для еще двух байтов вы можете очистить пространство шаблона перед заменой, что по-прежнему экономит два байта:
источник
В sed ближайшая к функции функция - это метка. Функция полезна, потому что вы можете выполнять ее код несколько раз, тем самым сохраняя много байтов. Однако в sed вам нужно будет указать метку возврата, и поэтому вы не можете просто вызывать эту «функцию» несколько раз по всему коду, как вы это делаете на других языках.
Обходной путь, который я использую, заключается в добавлении в одну из двух ячеек флага, который используется для выбора метки возврата. Это работает лучше всего, когда функциональному коду требуется только одно пространство памяти (другое).
Пример, показывающий, что я имею в виду: взят из моего проекта, чтобы написать небольшую игру в sed
Этикетки, конечно, должны быть обозначены только одной буквой, я использовал полные имена для лучшего объяснения.
источник
Пустые регулярные выражения эквивалентны ранее встреченному регулярному выражению
(спасибо Райли за то, что обнаружили это из анагольного представления )
Вот пример, где нам поручено создать 100
@
сек в пустом буфере.Второе решение на 1 байт короче и использует тот факт, что пустые регулярные выражения заполняются последним найденным регулярным выражением. Здесь, для второй замены, последнее регулярное выражение было
.*
, поэтому здесь пустое регулярное выражение будет заполнено.*
. Это также работает с регулярными выражениями в/conditionals/
.Обратите внимание, что это ранее встречалось регулярное выражение, поэтому следующее также будет работать.
Пустое регулярное выражение заполняется
@*
вместо,$
потому чтоs/$/@/
никогда не достигается.источник
В основном бесполезный шаг:
Это будет переводить только
A
наB
иy
кz
(... и-
к-
;), но ничего больше, такпросто вернется:
Вы могли бы обеспечить это будет бесполезно, для образца, используя это на шестнадцатеричных значений нижнего регистра (содержащего только
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
,a
,b
,c
,d
,e
илиf
.)источник
sed '; ;/s/b;y|A-y|B-z|;s ;s/ //; ; ;' <<<'Hello world'
(Почему это не подавляет пространство?)