mirror of
https://github.com/chmln/sd
synced 2024-11-22 03:03:03 +00:00
Improve README readability (#227)
* README: fix formatting of numbered Quick Guide examples * README: make The Pitch easier to read - less clutter - easier on the eyes. - previous format looks less concise and more wordy even though it's the same. * README: make Comparison to sed easier to read - nix deeply nested list, which just adds clutter. - make sure sed syntax is always lined up just below sd syntax for clear visual contrast * README: make title look and read better
This commit is contained in:
parent
3d7141477c
commit
05ee953299
1 changed files with 65 additions and 69 deletions
134
README.md
134
README.md
|
@ -1,4 +1,4 @@
|
|||
# sd - s[earch] & d[isplace]
|
||||
# sd - `s`earch & `d`isplace
|
||||
|
||||
`sd` is an intuitive find & replace CLI.
|
||||
|
||||
|
@ -6,43 +6,41 @@
|
|||
|
||||
Why use it over any existing tools?
|
||||
|
||||
**Painless regular expressions**
|
||||
*Painless regular expressions.* `sd` uses regex syntax that you already know from JavaScript and Python. Forget about dealing with quirks of `sed` or `awk` - get productive immediately.
|
||||
|
||||
`sd` uses regex syntax that you already know from JavaScript and Python. Forget about dealing with quirks of `sed` or `awk` - get productive immediately.
|
||||
*String-literal mode.* Non-regex find & replace. No more backslashes or remembering which characters are special and need to be escaped.
|
||||
|
||||
**String-literal mode**
|
||||
*Easy to read, easy to write.* Find & replace expressions are split up, which makes them easy to read and write. No more messing with unclosed and escaped slashes.
|
||||
|
||||
Non-regex find & replace. No more backslashes or remembering which characters are special and need to be escaped.
|
||||
|
||||
**Easy to read, easy to write**
|
||||
|
||||
Find & replace expressions are split up, which makes them easy to read and write. No more messing with unclosed and escaped slashes.
|
||||
|
||||
**Smart, common-sense defaults**
|
||||
|
||||
Defaults follow common sense and are tailored for typical daily use.
|
||||
*Smart, common-sense defaults.* Defaults follow common sense and are tailored for typical daily use.
|
||||
|
||||
## Comparison to sed
|
||||
|
||||
While sed does a whole lot more, `sd` focuses on doing just one thing and doing it well.
|
||||
While sed does a whole lot more, sd focuses on doing just one thing and doing it well. Here are some cherry-picked examples where sd shines.
|
||||
|
||||
Some cherry-picked examples, where `sd` shines:
|
||||
|
||||
- Simpler syntax for replacing all occurrences:
|
||||
Simpler syntax for replacing all occurrences:
|
||||
- sd: `sd before after`
|
||||
- sed: `sed s/before/after/g`
|
||||
- Replace newlines with commas:
|
||||
|
||||
Replace newlines with commas:
|
||||
- sd: `sd '\n' ','`
|
||||
- sed: `sed ':a;N;$!ba;s/\n/,/g'`
|
||||
- Extracting stuff out of strings containing slashes:
|
||||
|
||||
Extracting stuff out of strings containing slashes:
|
||||
- sd: `echo "sample with /path/" | sd '.*(/.*/)' '$1'`
|
||||
- sed: use different delimiters every time depending on expression so that the command is not completely unreadable
|
||||
- `echo "sample with /path/" | sed -E 's/.*(\\/.*\\/)/\1/g'`
|
||||
- `echo "sample with /path/" | sed -E 's|.*(/.*/)|\1|g'`
|
||||
- In place modification of files:
|
||||
- sed: `echo "sample with /path/" | sed -E 's/.*(\\/.*\\/)/\1/g'`
|
||||
|
||||
With sed, you can make it better with a different delimiter,
|
||||
but it is still messy:
|
||||
|
||||
`echo "sample with /path/" | sed -E 's|.*(/.*/)|\1|g'`
|
||||
|
||||
In place modification of files:
|
||||
- sd: `sd before after file.txt`
|
||||
- sed: you need to remember to use `-e` or else some platforms will consider the next argument to be a backup suffix
|
||||
- `sed -i -e 's/before/after/g' file.txt`
|
||||
- sed: `sed -i -e 's/before/after/g' file.txt`
|
||||
|
||||
With sed, you need to remember to use `-e` or else some
|
||||
platforms will consider the next argument to be a backup suffix.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
|
@ -92,75 +90,73 @@ Install through
|
|||
|
||||
1. **String-literal mode**. By default, expressions are treated as regex. Use `-s` or `--string-mode` to disable regex.
|
||||
|
||||
|
||||
```sh
|
||||
> echo 'lots((([]))) of special chars' | sd -s '((([])))' ''
|
||||
lots of special chars
|
||||
```
|
||||
|
||||
```sh
|
||||
> echo 'lots((([]))) of special chars' | sd -s '((([])))' ''
|
||||
lots of special chars
|
||||
```
|
||||
|
||||
2. **Basic regex use** - let's trim some trailing whitespace
|
||||
|
||||
```sh
|
||||
> echo 'lorem ipsum 23 ' | sd '\s+$' ''
|
||||
lorem ipsum 23
|
||||
```
|
||||
```sh
|
||||
> echo 'lorem ipsum 23 ' | sd '\s+$' ''
|
||||
lorem ipsum 23
|
||||
```
|
||||
|
||||
3. **Capture groups**
|
||||
|
||||
Indexed capture groups:
|
||||
Indexed capture groups:
|
||||
|
||||
```sh
|
||||
> echo 'cargo +nightly watch' | sd '(\w+)\s+\+(\w+)\s+(\w+)' 'cmd: $1, channel: $2, subcmd: $3'
|
||||
cmd: cargo, channel: nightly, subcmd: watch
|
||||
```
|
||||
```sh
|
||||
> echo 'cargo +nightly watch' | sd '(\w+)\s+\+(\w+)\s+(\w+)' 'cmd: $1, channel: $2, subcmd: $3'
|
||||
cmd: cargo, channel: nightly, subcmd: watch
|
||||
```
|
||||
|
||||
Named capture groups:
|
||||
Named capture groups:
|
||||
|
||||
```sh
|
||||
> echo "123.45" | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '$dollars dollars and $cents cents'
|
||||
123 dollars and 45 cents
|
||||
```
|
||||
```sh
|
||||
> echo "123.45" | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '$dollars dollars and $cents cents'
|
||||
123 dollars and 45 cents
|
||||
```
|
||||
|
||||
In the unlikely case you stumble upon ambiguities, resolve them by using `${var}` instead of `$var`. Here's an example:
|
||||
In the unlikely case you stumble upon ambiguities, resolve them by using `${var}` instead of `$var`. Here's an example:
|
||||
|
||||
```sh
|
||||
> echo '123.45' | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '$dollars_dollars and $cents_cents'
|
||||
and
|
||||
```sh
|
||||
> 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
|
||||
```
|
||||
> echo '123.45' | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '${dollars}_dollars and ${cents}_cents'
|
||||
123_dollars and 45_cents
|
||||
```
|
||||
|
||||
4. **Find & replace in a file**
|
||||
|
||||
```sh
|
||||
> sd 'window.fetch' 'fetch' http.js
|
||||
```
|
||||
```sh
|
||||
> sd 'window.fetch' 'fetch' http.js
|
||||
```
|
||||
|
||||
That's it. The file is modified in-place.
|
||||
That's it. The file is modified in-place.
|
||||
|
||||
To preview changes:
|
||||
To preview changes:
|
||||
|
||||
```sh
|
||||
> sd -p 'window.fetch' 'fetch' http.js
|
||||
```
|
||||
```sh
|
||||
> sd -p 'window.fetch' 'fetch' http.js
|
||||
```
|
||||
|
||||
5. **Find & replace across project**
|
||||
|
||||
This example uses [fd](https://github.com/sharkdp/fd).
|
||||
This example uses [fd](https://github.com/sharkdp/fd).
|
||||
|
||||
Good ol' unix philosophy to the rescue.
|
||||
Good ol' unix philosophy to the rescue.
|
||||
|
||||
```sh
|
||||
fd --type file --exec sd 'from "react"' 'from "preact"'
|
||||
```
|
||||
```sh
|
||||
fd --type file --exec sd 'from "react"' 'from "preact"'
|
||||
```
|
||||
|
||||
Same, but with backups (consider version control).
|
||||
Same, but with backups (consider version control).
|
||||
|
||||
```bash
|
||||
fd --type file --exec cp {} {}.bk \; --exec sd 'from "react"' 'from "preact"'
|
||||
```
|
||||
```bash
|
||||
fd --type file --exec cp {} {}.bk \; --exec sd 'from "react"' 'from "preact"'
|
||||
```
|
||||
|
||||
### Edge cases
|
||||
sd will interpret every argument starting with `-` as a (potentially unknown) flag.
|
||||
|
|
Loading…
Reference in a new issue