s
и d
sd
— это интуитивно понятный интерфейс командной строки для поиска и замены.
Зачем использовать его вместо любых существующих инструментов?
Безболезненные регулярные выражения. sd
использует синтаксис регулярных выражений, который вы уже знаете из JavaScript и Python. Забудьте о тонкостях sed
или awk
— сразу начните работать продуктивно.
Строковый литеральный режим. Поиск и замена без регулярных выражений. Больше не нужно использовать обратную косую черту или запоминать, какие символы являются особенными и их нужно экранировать.
Легко читать, легко писать. Выражения поиска и замены разделены, что упрощает их чтение и запись. Больше не нужно возиться с незакрытыми и экранированными косыми чертами.
Умные, разумные настройки по умолчанию. Значения по умолчанию соответствуют здравому смыслу и адаптированы для типичного повседневного использования.
В то время как sed делает гораздо больше, sd фокусируется на том, чтобы делать только одну вещь и делать ее хорошо. Вот несколько отобранных примеров, где SD сияет.
Более простой синтаксис для замены всех вхождений:
sd before after
sed s/before/after/g
Замените новые строки запятыми:
sd 'n' ','
sed ':a;N;$!ba;s/n/,/g'
Извлечение данных из строк, содержащих косые черты:
sd: echo "sample with /path/" | sd '.*(/.*/)' '$1'
sed: echo "sample with /path/" | sed -E 's/.*(\/.*\/)/1/g'
С помощью sed вы можете улучшить ситуацию, установив другой разделитель, но это по-прежнему беспорядочно:
echo "sample with /path/" | sed -E 's|.*(/.*/)|1|g'
По месту модификации файлов:
SD: sd before after file.txt
sed: sed -i -e 's/before/after/g' file.txt
При использовании sed вам нужно не забыть использовать -e
, иначе некоторые платформы будут считать следующий аргумент резервным суффиксом.
Простая замена на ~1,5 гигабайта JSON
hyperfine --warmup 3 --export-markdown out.md
' sed -E "s/"/ ' " ' " ' /g" *.json > /dev/null '
' sed "s/"/ ' " ' " ' /g" *.json > /dev/null '
' sd """ " ' " ' " ' " *.json > /dev/null '
Команда | Означает] | Мин…Макс [с] |
---|---|---|
sed -E "s/"/'/g" *.json > /dev/null | 2,338 ± 0,008 | 2,332…2,358 |
sed "s/"/'/g" *.json > /dev/null | 2,365 ± 0,009 | 2,351…2,378 |
sd """ "'" *.json > /dev/null | 0,997 ± 0,006 | 0,987…1,007 |
Результат: ~2,35 раза быстрее
Замена регулярных выражений в json-файле размером ~ 55M :
hyperfine --warmup 3 --export-markdown out.md
' sed -E "s:(w+):11:g" dump.json > /dev/null '
' sed "s:(w+):11:g" dump.json > /dev/null '
' sd "(w+)" "$1$1" dump.json > /dev/null '
Команда | Означает] | Мин…Макс [с] |
---|---|---|
sed -E "s:(w+):11:g" dump.json > /dev/null | 11,315 ± 0,215 | 11,102…11,725 |
sed "s:(w+):11:g" dump.json > /dev/null | 11,239 ± 0,208 | 11,057…11,762 |
sd "(w+)" "$1$1" dump.json > /dev/null | 0,942 ± 0,004 | 0,936…0,951 |
Результат: ~11,93 раза быстрее
Устанавливать через cargo
с помощью cargo install sd
, или через различные менеджеры пакетов.
Строковый литеральный режим . По умолчанию выражения рассматриваются как регулярные выражения. Используйте -F
или --fixed-strings
чтобы отключить регулярное выражение.
> echo ' lots((([]))) of special chars ' | sd -F ' ((([]))) ' ' '
lots of special chars
Базовое использование регулярных выражений – давайте обрежем конечные пробелы
> echo ' lorem ipsum 23 ' | sd ' s+$ ' ' '
lorem ipsum 23
Группы захвата
Индексированные группы захвата:
> echo ' cargo +nightly watch ' | sd ' (w+)s++(w+)s+(w+) ' ' cmd: $1, channel: $2, subcmd: $3 '
cmd: cargo, channel: nightly, subcmd: watch
Именованные группы захвата:
> echo " 123.45 " | sd ' (?P<dollars>d+).(?P<cents>d+) ' ' $dollars dollars and $cents cents '
123 dollars and 45 cents
В том маловероятном случае, когда вы столкнетесь с неоднозначностью, разрешите ее, используя ${var}
вместо $var
. Вот пример:
> echo ' 123.45 ' | sd ' (?P<dollars>d+).(?P<cents>d+) ' ' $dollars_dollars and $cents_cents '
and
> echo ' 123.45 ' | sd ' (?P<dollars>d+).(?P<cents>d+) ' ' ${dollars}_dollars and ${cents}_cents '
123_dollars and 45_cents
Найти и заменить в файле
> sd ' window.fetch ' ' fetch ' http.js
Вот и все. Файл изменяется на месте.
Чтобы просмотреть изменения:
> sd -p ' window.fetch ' ' fetch ' http.js
Найти и заменить в проекте
В этом примере используется fd.
Старая добрая философия Unix придет на помощь.
fd --type file --exec sd ' from "react" ' ' from "preact" '
То же, но с резервными копиями (учтите контроль версий).
fd --type file --exec cp {} {}.bk ; --exec sd ' from "react" ' ' from "preact" '
sd будет интерпретировать каждый аргумент, начинающийся с -
как (потенциально неизвестный) флаг. Соблюдается общепринятое соглашение об использовании --
для обозначения конца флагов:
$ echo " ./hello foo " | sd " foo " " -w "
error: Found argument ' -w ' which wasn ' t expected, or isn ' t valid in this context
USAGE:
sd [OPTIONS] < find > < replace-with > [files]...
For more information try --help
$ echo " ./hello foo " | sd " foo " -- " -w "
./hello -w
$ echo " ./hello --foo " | sd -- " --foo " " -w "
./hello -w
Чтобы экранировать символ $
, используйте $$
:
❯ echo " foo " | sd ' foo ' ' $$bar '
$bar