s
e d
sd
é uma CLI intuitiva para localizar e substituir.
Por que usá-lo em vez de qualquer ferramenta existente?
Expressões regulares indolores. sd
usa sintaxe regex que você já conhece de JavaScript e Python. Esqueça lidar com peculiaridades do sed
ou awk
– torne-se produtivo imediatamente.
Modo literal de string. Localizar e substituir não regex. Chega de barras invertidas ou de lembrar quais caracteres são especiais e precisam ser escapados.
Fácil de ler, fácil de escrever. As expressões Localizar e Substituir são divididas, o que as torna fáceis de ler e escrever. Chega de mexer com barras não fechadas e com escape.
Padrões inteligentes e de bom senso. Os padrões seguem o bom senso e são adaptados para uso diário típico.
Enquanto o sed faz muito mais, o sd se concentra em fazer apenas uma coisa e fazê-la bem. Aqui estão alguns exemplos escolhidos a dedo onde o sd brilha.
Sintaxe mais simples para substituir todas as ocorrências:
sd before after
sed s/before/after/g
Substitua novas linhas por vírgulas:
sd 'n' ','
sed ':a;N;$!ba;s/n/,/g'
Extraindo coisas de strings contendo barras:
sd: echo "sample with /path/" | sd '.*(/.*/)' '$1'
sed: echo "sample with /path/" | sed -E 's/.*(\/.*\/)/1/g'
Com sed, você pode melhorar com um delimitador diferente, mas ainda é confuso:
echo "sample with /path/" | sed -E 's|.*(/.*/)|1|g'
Modificação local de arquivos:
sd: sd before after file.txt
sed: sed -i -e 's/before/after/g' file.txt
Com sed, você precisa se lembrar de usar -e
, caso contrário, algumas plataformas considerarão o próximo argumento como um sufixo de backup.
Substituição simples em aproximadamente 1,5 gigabytes de 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 '
Comando | Significa] | Mínimo…Máx[s] |
---|---|---|
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 |
Resultado: ~2,35 vezes mais rápido
Substituição de Regex em um arquivo JSON de aproximadamente 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 '
Comando | Significa] | Mínimo…Máx[s] |
---|---|---|
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 |
Resultado: ~11,93 vezes mais rápido
Instale através de cargo
com cargo install sd
ou através de vários gerenciadores de pacotes
Modo literal de string . Por padrão, as expressões são tratadas como regex. Use -F
ou --fixed-strings
para desativar o regex.
> echo ' lots((([]))) of special chars ' | sd -F ' ((([]))) ' ' '
lots of special chars
Uso básico de regex - vamos cortar alguns espaços em branco à direita
> echo ' lorem ipsum 23 ' | sd ' s+$ ' ' '
lorem ipsum 23
Capturar grupos
Grupos de captura indexados:
> echo ' cargo +nightly watch ' | sd ' (w+)s++(w+)s+(w+) ' ' cmd: $1, channel: $2, subcmd: $3 '
cmd: cargo, channel: nightly, subcmd: watch
Grupos de captura nomeados:
> echo " 123.45 " | sd ' (?P<dollars>d+).(?P<cents>d+) ' ' $dollars dollars and $cents cents '
123 dollars and 45 cents
No caso improvável de você se deparar com ambigüidades, resolva-as usando ${var}
em vez de $var
. Aqui está um exemplo:
> 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
Localizar e substituir em um arquivo
> sd ' window.fetch ' ' fetch ' http.js
É isso. O arquivo é modificado no local.
Para visualizar alterações:
> sd -p ' window.fetch ' ' fetch ' http.js
Localizar e substituir em todo o projeto
Este exemplo usa fd.
A boa e velha filosofia unix para o resgate.
fd --type file --exec sd ' from "react" ' ' from "preact" '
O mesmo, mas com backups (considere o controle de versão).
fd --type file --exec cp {} {}.bk ; --exec sd ' from "react" ' ' from "preact" '
sd interpretará cada argumento começando com -
como um sinalizador (potencialmente desconhecido). A convenção comum de usar --
para sinalizar o fim dos sinalizadores é respeitada:
$ 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
Para escapar do caractere $
, use $$
:
❯ echo " foo " | sd ' foo ' ' $$bar '
$bar