Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Awesome Command-line Tools with saner defaults

Awesome Command-line Tools with saner defaults

This presentation gives a preview of alternatives to ls, grep and find: exa, ripgrep and fd. These modern command-line tools are ergonomic, ridiculously fast, and have nice colored output. These are all written in Rust, and can be installed easily on your favorite OS.

Michael Galero

November 15, 2018
Tweet

More Decks by Michael Galero

Other Decks in Programming

Transcript

  1. You list files hundreds of times a day. Why spend

    your time squinting at black and white text?
  2. exa A modern replacement for ls exa is an improved

    file lister with more features and better defaults. It uses colours to distinguish file types and metadata. It knows about symlinks, extended attributes, and Git. And it’s small, fast and just one single binary. Source: https://the.exa.website
  3. exa • Colors • Long View • Tree View •

    Git Support • Installation • Alias
  4. “For both searching single files and huge directories of files,

    no other tool obviously stands above ripgrep in either performance or correctness.” - Andrew Gallant
  5. ripgrep Faster than {grep, ag, git grep, ucg, pt, sift}

    ripgrep is a line-oriented search tool that recursively searches your current directory for a regex pattern while respecting your gitignore rules. [It] has first class support on Windows, macOS and Linux, with binary downloads available for every release. Source: https://github.com/burntsushi/ripgrep
  6. • Basics • Regex • Recursive • Automatic Filtering •

    Search by file type • File Encoding • Performance • Installation ripgrep
  7. Basics $ grep hanbaiki README.md If you're interested to know

    the meaning of the name, see [project name page](https://mikong.github.io/hanbaiki/name.html). $ git clone [email protected]:mikong/hanbaiki.git $ ./target/debug/hanbaiki For a work-in-progress list of commands, check the [commands page](https://mikong.github.io/hanbaiki/commands.html). This software is distributed under the [MIT License](https://github.com/mikong/hanbaiki/blob/master/LICENSE).
  8. Basics $ rg hanbaiki README.md 5:If you're interested to know

    the meaning of the name, see [project name page](https://mikong.github.io/hanbaiki/name.html). 14:$ git clone [email protected]:mikong/hanbaiki.git 20:$ ./target/debug/hanbaiki 34:For a work-in-progress list of commands, check the [commands page](https://mikong.github.io/hanbaiki/commands.html). 38:This software is distributed under the [MIT License](https://github.com/mikong/hanbaiki/blob/master/LICENSE).
  9. Recursive $ grep -r --exclude-dir target 'InvalidData' . ./src/resp_error.rs: InvalidData(String),

    ./src/resp_error.rs: RespError::InvalidData(s) => write!(f, "{}", s), ./src/respwriter.rs: return Err(RespError::InvalidData("Contains CR or LF".to_string()));
  10. Recursive $ rg 'InvalidData' src/resp_error.rs 6: InvalidData(String), 27: RespError::InvalidData(s) =>

    write!(f, "{}", s), src/respwriter.rs 18: return Err(RespError::InvalidData("Contains CR or LF".to_string()));
  11. Automatic Filtering 1. Files and directories that match the rules

    in your .gitignore 2. Hidden files and directories 3. Binary files (files with NUL byte) 4. Symbolic links aren’t followed
  12. Disable Automatic Filtering 1. --no-ignore 2. --hidden 3. --text or

    -a (same as grep ) 4. --follow or -L (for grep , -S ) Alternatively, • --unrestricted or -u for 1 • -uu for 1 + 2 • -uuu for 1 + 2 + 3
  13. Filter by File Type $ rg 'TODO' -g '*.rb' $

    rg 'TODO' --type ruby // includes *.gemspec, *.rb, .irbrc, Gemfile, Rakefile $ rg 'TODO' --truby // same as above
  14. Custom File Types $ rg --type-list $ export RIPGREP_CONFIG_PATH=$HOME/.ripgreprc $

    cat $HOME/.ripgreprc # Add custom 'web' type. --type-add web:*.{html,css,js}*
  15. File Encoding • Assumes input is ASCII compatible • Works

    best with UTF-8 • Checks if UTF-16 • Specify encoding with --encoding or -E • Does not require valid UTF-8 • Unicode support can be disabled within regex • Read: GUIDE.md#file-encoding
  16. Performance Tool Command Line count Time ripgrep (Unicode) rg -n

    -w '[A-Z]+_SUSPEND' 450 0.106s git grep LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND' 450 0.553s The Silver Searcher ag -w '[A-Z]+_SUSPEND' 450 0.589s git grep (Unicode) LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND' 450 2.266s sift sift --git -n -w '[A-Z]+_SUSPEND' 450 3.505s ack ack -w '[A-Z]+_SUSPEND' 1878* 6.823s The Platinum Searcher pt -w -e '[A-Z]+_SUSPEND' 450 14.208s
  17. Performance Tool Command Line count Time ripgrep rg -L -u

    -tc -n -w '[A-Z]+_SUSPEND' 404 0.079s ucg ucg --type=cc -w '[A-Z]+_SUSPEND' 390* 0.163s GNU grep egrep -R -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND' 404 0.611s
  18. Performance Tool Command Line count Time ripgrep rg -w 'Sherlock

    [A-Z]\w+' 5268 2.108s GNU grep LC_ALL=C egrep -w 'Sherlock [A-Z]\w+' 5268 7.014s
  19. While it does not seek to mirror all of find’s

    powerful functionality, it provides sensible (opinionated) defaults for 80% of the use cases.
  20. fd ★ 7337 fd is a simple, fast and user-friendly

    alternative to find. The command name is 50% shorter than find. Source: https://github.com/sharkdp/fd
  21. fd • Basics • Automatic Filtering • Search Path •

    Regex • Search by file extension • Performance • Installation
  22. Excluding paths with find $ find . \( -path ./.git

    -o -path ./_book \) -prune -o -iname *config* -print ./src/config.rs ./src/client/config.rs
  23. Automatic Filtering with fd 1. Folders (and does not show

    files) that match one of the .gitignore patterns 2. Hidden directories (and does not show hidden files)
  24. Performance • Benchmark by the author • ~190,000 subdirectories, ~1M

    files • Check project README for more details
  25. Performance Tool Command Time (mean ± σ ) find with

    regex find ~ -iregex '.*[0-9]\.jpg$' 7.236s ± 0.090s find without regex find ~ -iname '*[0-9].jpg' 3.914s ± 0.027s fd, --hidden and --no-ignore fd -HI '.*[0-9]\.jpg$' ~ 811.6ms ± 26.9ms fd fd '[0-9]\.jpg$' ~ 123.7ms ± 6.0ms
  26. • Ruby developer learning Rust • Twitter: @mikong • Github:

    mikong Thanks! {\__/} ( • . •) / > u want this?