s
搜索和d
sd
是一个直观的查找和替换 CLI。
为什么要使用它而不是任何现有工具?
无痛的正则表达式。 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 GB 的 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 '
命令 | 方法] | 最小…最大 [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 |
结果:快约 2.35 倍
约 55M json 文件的正则表达式替换:
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 '
命令 | 方法] | 最小…最大 [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 |
结果:约快 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