Bash often coordinates search tools. find locates candidate files, and grep checks their contents.

Program

Play the script to see a project search narrow from package.json directories to a file containing login.

find_grep.sh
Replay: real traced execution (multi-file project)
#!/usr/bin/env bash

root="$(mktemp -d)"
mkdir -p "$root/app" "$root/docs"
printf '{"scripts":{"test":"echo ok"}}\n' > "$root/app/package.json"
printf 'login screen\n' > "$root/app/login.txt"
match="$(find "$root" -name package.json -exec dirname {} \; | while read -r dir; do grep -l "login" "$dir"/* 2>/dev/null | sed "s|$root/||"; done)"
rm -rf "$root"
echo "$match"
  1. root ← /tmp/tmp.project

    3root="$(mktemp -d)"4mkdir -p "$root/app" "$root/docs"
    values this step/tmp/tmp.projectroot
  2. dirs ← app, docs

    3root="$(mktemp -d)"4mkdir -p "$root/app" "$root/docs"5printf '{"scripts":{"test":"echo ok"}}\n' > "$root/app/package.json"
    values this stepapp, docsdirs/tmp/tmp.projectroot
  3. package.json ← app/package.json

    4mkdir -p "$root/app" "$root/docs"5printf '{"scripts":{"test":"echo ok"}}\n' > "$root/app/package.json"6printf 'login screen\n' > "$root/app/login.txt"
    values this stepapp/package.jsonpackage.json
  4. login.txt ← contains login

    5printf '{"scripts":{"test":"echo ok"}}\n' > "$root/app/package.json"6printf 'login screen\n' > "$root/app/login.txt"7match="$(find "$root" -name package.json -exec dirname {} \; | while read -r dir; do grep -l "login" "$dir"/* 2>/dev/null | sed "s|$root/||"; done)"
    values this stepcontains loginlogin.txt
  5. package dirs ← app, match ← app/login.txt

    6printf 'login screen\n' > "$root/app/login.txt"7match="$(find "$root" -name package.json -exec dirname {} \; | while read -r dir; do grep -l "login" "$dir"/* 2>/dev/null | sed "s|$root/||"; done)"8rm -rf "$root"
    values this stepapppackage dirsapp/login.txtmatch/tmp/tmp.projectroot
  6. root ← removed

    7match="$(find "$root" -name package.json -exec dirname {} \; | while read -r dir; do grep -l "login" "$dir"/* 2>/dev/null | sed "s|$root/||"; done)"8rm -rf "$root"9echo "$match"
    values this step/tmp/tmp.project removedroot
  7. echo "$match"

    8rm -rf "$root"9echo "$match"
    outputapp/login.txt
    values this stepapp/login.txtmatch
find `find` walks directories and selects paths by name, type, and other tests.
grep `grep` searches file contents for matching text.