linux-file-directory-search.md (15872B)
1 --- 2 title: "Linux File & Directory Search" 3 description: "A comprehensive guide to find, grep, fd, and rg (ripgrep) for locating files and searching content." 4 category: linux-it 5 tags: ["linux-it"] 6 tools: ["PowerShell"] 7 difficulty: intermediate 8 updated: "2026-08-10" 9 source: "vault:Linux/Linux File & Directory Search Cheat Sheet.md" 10 --- 11 # Linux File & Directory Search Cheat Sheet 12 13 A comprehensive guide to `find`, `grep`, `fd`, and `rg` (ripgrep) for locating files and searching content. 14 15 --- 16 17 ## Table of Contents 18 1. [find - Classic File Search](#find) 19 2. [grep - Content Search](#grep) 20 3. [fd - Modern find Alternative](#fd) 21 4. [rg (ripgrep) - Modern grep Alternative](#rg) 22 5. [Combined Patterns & Workflows](#combined) 23 6. [Windows findstr Equivalents](#windows-equivalents) 24 25 --- 26 27 ## <a name="find"></a>1. `find` - Classic File Search 28 29 ### Basic Syntax 30 ```bash 31 find [path] [options] [expression] 32 ``` 33 34 ### Finding Files by Name 35 ```bash 36 # Find by exact name 37 find /path -name "filename.txt" 38 39 # Case-insensitive search 40 find /path -iname "filename.txt" 41 42 # Wildcards (must be quoted) 43 find . -name "*.ps1" 44 find . -name "*.log" 45 find . -name "Password_File*" 46 47 # Multiple patterns (OR logic) 48 find . -name "*.ps1" -o -name "*.sh" -o -name "*.py" 49 50 # Regex matching (full path) 51 find . -regex ".*\(\.ps1\|\.sh\)$" 52 53 # Extended regex 54 find . -regextype posix-extended -regex ".*(POWERSHELL_SCRIPT|Password_File|.*\.ps1)" 55 ``` 56 57 ### Finding by Type 58 59 ```bash 60 # Files only 61 find . -type f 62 63 # Directories only 64 find . -type d 65 66 # Symbolic links 67 find . -type l 68 69 # Empty files 70 find . -type f -empty 71 72 # Empty directories 73 find . -type d -empty 74 ``` 75 76 ### Finding by Size 77 78 ```bash 79 # Exactly 50MB 80 find . -size 50M 81 82 # Greater than 100MB 83 find . -size +100M 84 85 # Less than 1KB 86 find . -size -1k 87 88 # Between 1MB and 100MB 89 find . -size +1M -size -100M 90 91 # Size units: c(bytes), k(KB), M(MB), G(GB) 92 ``` 93 94 ### Finding by Time 95 96 ```bash 97 # Modified in last 7 days 98 find . -mtime -7 99 100 # Modified more than 30 days ago 101 find . -mtime +30 102 103 # Modified exactly 1 day ago 104 find . -mtime 1 105 106 # Accessed in last 60 minutes 107 find . -amin -60 108 109 # Changed in last 24 hours (metadata) 110 find . -ctime -1 111 112 # Modified after a reference file 113 find . -newer reference_file.txt 114 115 # Modified between two dates 116 find . -newermt "2024-01-01" ! -newermt "2024-12-31" 117 ``` 118 119 ### Finding by Permissions & Ownership 120 121 ```bash 122 # Exact permissions 123 find . -perm 644 124 find . -perm 755 125 126 # At least these permissions (all bits set) 127 find . -perm -644 128 129 # Any of these permissions (any bit set) 130 find . -perm /644 131 132 # World-writable files (security audit) 133 find . -perm -o=w -type f 134 135 # SUID/SGID files 136 find . -perm /4000 # SUID 137 find . -perm /2000 # SGID 138 find . -perm /6000 # Either 139 140 # By owner 141 find . -user username 142 find . -group groupname 143 144 # Files without owner (orphaned) 145 find . -nouser 146 find . -nogroup 147 ``` 148 149 ### Depth Control 150 151 ```bash 152 # Maximum depth (don't go deeper than 2 levels) 153 find . -maxdepth 2 -name "*.txt" 154 155 # Minimum depth (skip current directory) 156 find . -mindepth 1 -name "*.txt" 157 158 # Exact depth (only level 3) 159 find . -mindepth 3 -maxdepth 3 -name "*.txt" 160 ``` 161 162 ### Excluding Paths 163 164 ```bash 165 # Exclude a directory 166 find . -path "./node_modules" -prune -o -name "*.js" -print 167 168 # Exclude multiple directories 169 find . \( -path "./node_modules" -o -path "./.git" \) -prune -o -name "*.js" -print 170 171 # Using -not 172 find . -not -path "*/\.git/*" -name "*.py" 173 ``` 174 175 ### Actions 176 177 ```bash 178 # Delete found files (DANGEROUS - test with -print first!) 179 find . -name "*.tmp" -delete 180 181 # Execute command on each file 182 find . -name "*.txt" -exec cat {} \; 183 184 # Execute with confirmation 185 find . -name "*.log" -ok rm {} \; 186 187 # More efficient execution (batched) 188 find . -name "*.txt" -exec cat {} + 189 190 # Print with null separator (for xargs) 191 find . -name "*.txt" -print0 | xargs -0 cat 192 193 # Custom output format 194 find . -name "*.txt" -printf "%p %s %T+\n" 195 # %p=path, %s=size, %T+=modification time 196 ``` 197 198 ### Complex Expressions 199 200 ```bash 201 # AND (implicit) 202 find . -name "*.txt" -size +1M 203 204 # AND (explicit) 205 find . -name "*.txt" -a -size +1M 206 207 # OR 208 find . -name "*.txt" -o -name "*.md" 209 210 # NOT 211 find . ! -name "*.txt" 212 find . -not -name "*.txt" 213 214 # Grouping with parentheses 215 find . \( -name "*.txt" -o -name "*.md" \) -mtime -7 216 ``` 217 218 --- 219 220 ## <a name="grep"></a>2. `grep` - Content Search 221 222 ### Basic Syntax 223 ```bash 224 grep [options] pattern [file...] 225 ``` 226 227 ### Basic Pattern Matching 228 229 ```bash 230 # Simple string search 231 grep "password" file.txt 232 233 # Search in multiple files 234 grep "password" *.txt 235 236 # Recursive search in directory 237 grep -r "password" /path/to/dir 238 239 # Case-insensitive 240 grep -i "password" file.txt 241 242 # Whole word only 243 grep -w "password" file.txt 244 245 # Fixed string (no regex interpretation) 246 grep -F "exact.string" file.txt 247 ``` 248 249 ### Regular Expressions 250 251 ```bash 252 # Extended regex 253 grep -E "POWERSHELL_SCRIPT|Password_File|.*\.ps1" . 254 255 # Perl-compatible regex (PCRE) 256 grep -P "password\d{3}" file.txt 257 258 # Match beginning of line 259 grep "^start" file.txt 260 261 # Match end of line 262 grep "end$" file.txt 263 264 # Match any character 265 grep "p.ssword" file.txt 266 267 # Character class 268 grep "[Pp]assword" file.txt 269 270 # Negated character class 271 grep "[^0-9]" file.txt 272 273 # Quantifiers 274 grep -E "ab+" file.txt # One or more 275 grep -E "ab*" file.txt # Zero or more 276 grep -E "ab?" file.txt # Zero or one 277 grep -E "a{3}" file.txt # Exactly 3 278 grep -E "a{2,5}" file.txt # 2 to 5 times 279 ``` 280 281 ### Output Control 282 283 ```bash 284 # Show line numbers 285 grep -n "pattern" file.txt 286 287 # Show only matching part 288 grep -o "pattern" file.txt 289 290 # Count matches 291 grep -c "pattern" file.txt 292 293 # Show filename only 294 grep -l "pattern" *.txt 295 296 # Show files without matches 297 grep -L "pattern" *.txt 298 299 # Show context (before/after/both) 300 grep -B 3 "pattern" file.txt # 3 lines before 301 grep -A 3 "pattern" file.txt # 3 lines after 302 grep -C 3 "pattern" file.txt # 3 lines both sides 303 304 # Suppress errors 305 grep -s "pattern" file.txt 306 307 # Quiet mode (exit code only) 308 grep -q "pattern" file.txt && echo "Found" 309 ``` 310 311 ### Recursive & File Filtering 312 313 ```bash 314 # Recursive search 315 grep -r "pattern" /path 316 317 # Recursive following symlinks 318 grep -R "pattern" /path 319 320 # Include only certain files 321 grep -r --include="*.py" "pattern" . 322 323 # Exclude files 324 grep -r --exclude="*.log" "pattern" . 325 326 # Exclude directories 327 grep -r --exclude-dir=".git" "pattern" . 328 grep -r --exclude-dir={.git,node_modules,vendor} "pattern" . 329 ``` 330 331 ### Inverting & Combining 332 333 ```bash 334 # Invert match (lines NOT matching) 335 grep -v "pattern" file.txt 336 337 # Multiple patterns (OR) 338 grep -E "pattern1|pattern2" file.txt 339 grep -e "pattern1" -e "pattern2" file.txt 340 341 # Multiple patterns from file 342 grep -f patterns.txt file.txt 343 344 # AND logic (all patterns must match) 345 grep "pattern1" file.txt | grep "pattern2" 346 grep -P "(?=.*pattern1)(?=.*pattern2)" file.txt 347 ``` 348 349 ### Binary & Special Files 350 351 ```bash 352 # Treat binary as text 353 grep -a "pattern" binary_file 354 355 # Skip binary files 356 grep -I "pattern" * 357 358 # Search compressed files 359 zgrep "pattern" file.gz 360 bzgrep "pattern" file.bz2 361 xzgrep "pattern" file.xz 362 ``` 363 364 --- 365 366 ## <a name="fd"></a>3. `fd` - Modern find Alternative 367 368 > **Installation**: `apt install fd-find` (Debian/Ubuntu), `brew install fd` (macOS), `cargo install fd-find` 369 > Note: On Debian/Ubuntu, the binary is `fdfind` 370 371 ### Basic Usage 372 373 ```bash 374 # Simple search (case-insensitive by default) 375 fd pattern 376 377 # Search in specific directory 378 fd pattern /path/to/dir 379 380 # Case-sensitive search 381 fd -s Pattern 382 383 # Exact match 384 fd -g "exact_filename.txt" 385 386 # Show full path 387 fd -a pattern 388 ``` 389 390 ### File Type Filtering 391 392 ```bash 393 # Files only 394 fd -t f pattern 395 396 # Directories only 397 fd -t d pattern 398 399 # Symbolic links 400 fd -t l pattern 401 402 # Executables 403 fd -t x pattern 404 405 # Empty files/directories 406 fd -t e pattern 407 408 # Specific extension 409 fd -e txt 410 fd -e py 411 fd -e ps1 412 413 # Multiple extensions 414 fd -e txt -e md -e rst 415 ``` 416 417 ### Advanced Patterns 418 419 ```bash 420 # Regex (default) 421 fd ".*\.(ps1|sh|py)$" 422 423 # Glob pattern 424 fd -g "*.ps1" 425 fd -g "Password_File*" 426 427 # Multiple patterns (Windows findstr equivalent) 428 fd -g "POWERSHELL_SCRIPT" . && fd -g "Password_File*" . && fd -e ps1 429 # Or using regex: 430 fd "(POWERSHELL_SCRIPT|Password_File|.*\.ps1)" 431 432 # Hidden files included 433 fd -H pattern 434 435 # Ignored files included (.gitignore) 436 fd -I pattern 437 438 # Both hidden and ignored 439 fd -HI pattern 440 ``` 441 442 ### Filtering & Exclusions 443 444 ```bash 445 # Exclude pattern 446 fd -E "*.log" pattern 447 fd -E node_modules pattern 448 449 # Multiple exclusions 450 fd -E node_modules -E .git -E target pattern 451 452 # Use .gitignore rules (default) 453 fd pattern 454 455 # Ignore .gitignore 456 fd -I pattern 457 458 # Exclude directories 459 fd -E ".git/" -E "node_modules/" pattern 460 ``` 461 462 ### Size & Time Filters 463 464 ```bash 465 # Size filters 466 fd -S +1M # Larger than 1MB 467 fd -S -100k # Smaller than 100KB 468 fd -S +1M -S -100M # Between 1MB and 100MB 469 470 # Time filters 471 fd --changed-within 1d # Changed in last day 472 fd --changed-within 2h # Changed in last 2 hours 473 fd --changed-before 1w # Changed more than 1 week ago 474 ``` 475 476 ### Depth Control 477 478 ```bash 479 # Maximum depth 480 fd -d 2 pattern 481 482 # Exact depth 483 fd --min-depth 2 --max-depth 2 pattern 484 ``` 485 486 ### Execution 487 488 ```bash 489 # Execute command on each result 490 fd -e txt -x cat {} 491 492 # Execute with placeholders 493 fd -e txt -x echo "File: {}" "Dir: {//}" "Name: {/}" "Base: {.}" 494 # {} = full path 495 # {//} = parent directory 496 # {/} = filename 497 # {.} = filename without extension 498 # {/.} = filename without extension, no path 499 500 # Parallel execution (default) 501 fd -e txt -x wc -l {} 502 503 # Batch execution 504 fd -e txt -X cat {} 505 506 # Delete files 507 fd -e tmp -X rm {} 508 ``` 509 510 ### Output Formatting 511 512 ```bash 513 # Null separator (for xargs) 514 fd -0 pattern | xargs -0 command 515 516 # Absolute paths 517 fd -a pattern 518 519 # Color control 520 fd --color=always pattern | less -R 521 fd --color=never pattern 522 ``` 523 524 --- 525 526 ## <a name="rg"></a>4. `rg` (ripgrep) - Modern grep Alternative 527 528 > **Installation**: `apt install ripgrep` (Debian/Ubuntu), `brew install ripgrep` (macOS), `cargo install ripgrep` 529 530 ### Basic Usage 531 532 ```bash 533 # Simple search (recursive by default) 534 rg "pattern" 535 536 # Search specific file 537 rg "pattern" file.txt 538 539 # Search specific directory 540 rg "pattern" /path/to/dir 541 542 # Case-insensitive 543 rg -i "pattern" 544 545 # Case-sensitive (default) 546 rg -s "pattern" 547 548 # Smart case (insensitive unless uppercase present) 549 rg -S "pattern" 550 ``` 551 552 ### Pattern Types 553 554 ```bash 555 # Regex (default) 556 rg "POWERSHELL_SCRIPT|Password_File|.*\.ps1" 557 558 # Fixed string (literal) 559 rg -F "exact.string" 560 561 # Word boundary 562 rg -w "word" 563 564 # Whole line 565 rg -x "entire line must match" 566 567 # Multiline 568 rg -U "pattern\nacross\nlines" 569 570 # PCRE2 regex 571 rg -P "(?i)password(?=.*\d)" 572 ``` 573 574 ### File Type Filtering 575 576 ```bash 577 # By type 578 rg -t py "pattern" # Python files 579 rg -t js "pattern" # JavaScript files 580 rg -t sh "pattern" # Shell scripts 581 582 # Multiple types 583 rg -t py -t js "pattern" 584 585 # List available types 586 rg --type-list 587 588 # Exclude type 589 rg -T js "pattern" 590 591 # Custom type definition 592 rg --type-add 'config:*.{conf,cfg,ini}' -t config "pattern" 593 594 # By glob 595 rg -g "*.py" "pattern" 596 rg -g "*.{py,js,ts}" "pattern" 597 598 # Exclude by glob 599 rg -g "!*.log" "pattern" 600 rg -g "!node_modules/**" "pattern" 601 ``` 602 603 ### Output Control 604 605 ```bash 606 # Line numbers (default on) 607 rg -n "pattern" 608 609 # No line numbers 610 rg -N "pattern" 611 612 # Show only filenames 613 rg -l "pattern" 614 615 # Show files without matches 616 rg --files-without-match "pattern" 617 618 # Count matches per file 619 rg -c "pattern" 620 621 # Only matching text 622 rg -o "pattern" 623 624 # Context lines 625 rg -B 3 "pattern" # 3 before 626 rg -A 3 "pattern" # 3 after 627 rg -C 3 "pattern" # 3 both 628 629 # Replace matches 630 rg "pattern" -r "replacement" 631 632 # Show column number 633 rg --column "pattern" 634 ``` 635 636 ### Hidden & Ignored Files 637 638 ```bash 639 # Search hidden files 640 rg --hidden "pattern" 641 642 # Ignore .gitignore 643 rg --no-ignore "pattern" 644 645 # Ignore .ignore and .gitignore 646 rg --no-ignore-vcs "pattern" 647 648 # Everything (hidden + all ignore files) 649 rg -uuu "pattern" 650 # -u = --no-ignore 651 # -uu = --no-ignore --hidden 652 # -uuu = --no-ignore --hidden --binary 653 ``` 654 655 ### Performance Options 656 657 ```bash 658 # Follow symlinks 659 rg -L "pattern" 660 661 # Limit results 662 rg -m 5 "pattern" 663 664 # Memory map (faster for large files) 665 rg --mmap "pattern" 666 667 # Thread count 668 rg -j 4 "pattern" 669 ``` 670 671 ### Advanced Features 672 673 ```bash 674 # JSON output 675 rg --json "pattern" 676 677 # Null separator 678 rg -0 -l "pattern" | xargs -0 command 679 680 # Stats 681 rg --stats "pattern" 682 683 # Debug regex 684 rg --debug "pattern" 685 686 # Trace file searching 687 rg --trace "pattern" 688 689 # Search binary files 690 rg -a "pattern" 691 692 # Search compressed files (requires preprocessing) 693 zcat file.gz | rg "pattern" 694 ``` 695 696 --- 697 698 ## <a name="combined"></a>5. Combined Patterns & Workflows 699 700 ### Find Files Then Search Content 701 702 ```bash 703 # Using find + grep 704 find . -name "*.py" -exec grep -l "import os" {} \; 705 706 # Using find + xargs (more efficient) 707 find . -name "*.py" -print0 | xargs -0 grep -l "import os" 708 709 # Using fd + rg 710 fd -e py -x rg -l "import os" {} 711 712 # Find and search in one command 713 fd -e py --exec rg "import os" {} 714 ``` 715 716 ### Complex Search Scenarios 717 718 ```bash 719 # Find large log files modified today 720 find . -name "*.log" -size +10M -mtime 0 721 fd -e log -S +10M --changed-within 1d 722 723 # Find all scripts and search for passwords 724 find . \( -name "*.sh" -o -name "*.py" -o -name "*.ps1" \) -exec grep -i "password" {} + 725 fd -e sh -e py -e ps1 -x rg -i "password" {} 726 727 # Find empty directories and delete 728 find . -type d -empty -delete 729 fd -t d -t e -X rmdir {} 730 731 # Find duplicate filenames 732 find . -type f -printf "%f\n" | sort | uniq -d 733 734 # Security audit: world-writable files 735 find / -type f -perm -o=w 2>/dev/null 736 ``` 737 738 ### Creating File Lists 739 740 ```bash 741 # All Python files to a list 742 find . -name "*.py" > python_files.txt 743 fd -e py > python_files.txt 744 745 # Files with specific content 746 grep -r -l "TODO" . > todo_files.txt 747 rg -l "TODO" > todo_files.txt 748 749 # Sorted by modification time 750 find . -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f2- 751 ``` 752 753 --- 754 755 ## <a name="windows-equivalents"></a>6. Windows `findstr` Equivalents 756 757 The Windows command: 758 ```cmd 759 findstr "POWERSHELL_SCRIPT|Password_File|*.ps1" 760 ``` 761 762 ### Equivalent in Linux Tools 763 764 | Task | Linux Command | 765 |:-----|:--------------| 766 | **Search file names** | `find . -regex ".*\(POWERSHELL_SCRIPT\|Password_File\|.*\.ps1\)"` | 767 | **Search file names (fd)** | `fd "(POWERSHELL_SCRIPT\|Password_File\|.*\.ps1)"` | 768 | **Search file content** | `grep -rE "POWERSHELL_SCRIPT\|Password_File" --include="*.ps1" .` | 769 | **Search file content (rg)** | `rg "POWERSHELL_SCRIPT\|Password_File" -t ps1` | 770 | **Combined (names + content)** | See below | 771 772 ### Combined Search (Names AND Content) 773 774 ```bash 775 # Find files matching name patterns, then search inside them 776 find . \( -name "*POWERSHELL*" -o -name "*Password_File*" -o -name "*.ps1" \) \ 777 -exec grep -l "sensitive_pattern" {} \; 778 779 # Using fd + rg 780 fd "(POWERSHELL_SCRIPT|Password_File|.*\.ps1)" -x rg -l "sensitive_pattern" {} 781 782 # Find .ps1 files containing specific patterns 783 rg -t ps1 "POWERSHELL_SCRIPT|Password_File" 784 ``` 785 786 --- 787 788 ## Quick Reference Card 789 790 | Task | find | fd | grep | rg | 791 |:-----|:-----|:---|:-----|:---| 792 | Find by name | `find . -name "*.txt"` | `fd -e txt` | N/A | N/A | 793 | Find files only | `find . -type f` | `fd -t f` | N/A | N/A | 794 | Case insensitive | `find . -iname` | default | `grep -i` | `rg -i` | 795 | Regex | `-regex` | default | `grep -E` | default | 796 | Recursive | default | default | `grep -r` | default | 797 | Exclude dir | `-path X -prune` | `-E dir/` | `--exclude-dir` | `-g "!dir/"` | 798 | Execute | `-exec cmd {} \;` | `-x cmd {}` | N/A | N/A | 799 | Hidden files | default | `-H` | default | `--hidden` | 800 | Size filter | `-size +10M` | `-S +10M` | N/A | N/A | 801 | Time filter | `-mtime -7` | `--changed-within 7d` | N/A | N/A | 802 803 --- 804 805 ## Pro Tips 806 807 1. **Always quote patterns** with wildcards to prevent shell expansion 808 2. **Use `-print0` / `-0`** for filenames with spaces 809 3. **Test destructive commands** with `-print` or `echo` first 810 4. **`fd` and `rg` respect `.gitignore`** by default - use `-I`/`--no-ignore` to override 811 5. **Combine tools** for complex workflows: `fd ... | xargs rg ...` 812 6. **Use `--` to separate** options from patterns starting with `-`