Offered solutions could be better quality. There are a number of unsolved issues with the given answers:
If you don't know where to look, then searching the entire filesystem isn't as trivial as specifying the root directory on linux. There's some stuff to exclude. What?
Following symlinks can lead to loops which means the search never terminates and never investigates some of the files on the disk.
In most cases, you do not want to search inside virtual directories like /dev/
, /proc/
and /sys/
, because that will spew errors, and not search actual files on disk, instead searching program memory and raw device data, causing the search to take very, very long.
You probably also don't want to search in /tmp/
, which is usually a memory-mounted filesystem that is purged upon reboot and automatically cleaned on modern Linuxes.
The terminal has a limited capacity for text. If this is exceeded, results are lost. Results should be put in a file.
If the terminal connection drops at any point in the search, results are lost and everything has to be restarted. Running in the background would be much preferred.
Searching for code, with all the examples, is still very tricky on the command line. In particular: Escaping stuff. In particular:
Various special characters in bash have to be escaped.
Grep searches for a regex which has to be escaped.
If commands are put into other commands, that leads to more things being escaped.
All three combined when searching code is a literal nightmare to figure out: the user should have an input for what to search for that does not require any escaping.
Filenames can have special characters in them, mucking with your search. The command should be able to deal with evil filenames with quotes and spaces and newlines and other shenanigans in them.
Files could be removed or changed while you're searching, leading to 'File not Found' errors cluttering the output. You could not have permission to things, also cluttering the output. Including an option to suppress errors helps.
Most of the examples use only a single thread, making them unnecessarily dreadfully slow on modern many-core servers, even though the task is embarrasingly parallel. The search command should start one thread per CPU core to keep it busy.
The following should be a big improvement:
# Note: Change search string below here.
nCores=$(nproc --all)
read -r -d '' sSearch <<'EOF'
echo $locale["timezone"]." ".$locale['offset'].PHP_EOL;
EOF
find -print0 \( -type f \) -and \( -not \( -type l \) \) -and \( -not \( -path "./proc/*" -o -path "./sys/*" -o -path "./tmp/*" -o -path "./dev/*" \) \) | xargs -P $nCores -0 grep -Fs "$sSearch" | tee /home/npr/results.txt &
If you do not want to suppress grep errors, use this:
# Note: Change search string below here.
nCores=$(nproc --all)
read -r -d '' sSearch <<'EOF'
echo $locale["timezone"]." ".$locale['offset'].PHP_EOL;
EOF
find -print0 \( -type f \) -and \( -not \( -type l \) \) -and \( -not \( -path "./proc/*" -o -path "./sys/*" -o -path "./tmp/*" -o -path "./dev/*" \) \) | xargs -P $nCores -0 grep -F "$sSearch" | tee /home/npr/results.txt &
Change EOF
to any other A-Za-z
variable if it's desired to search for the literal text EOF
.
With this, I reduced a day-long search that had thousands of errors resulting from several of the top answers here into an easy sub 1-minute command.
Reference:
Also see these answers:
running bash pipe commands in background with & ampersand
How do I exclude a directory when using `find`? (most answers were wrong and I had to fix it for modern find).
https://unix.stackexchange.com/questions/172481/how-to-quote-arguments-with-xargs
https://unix.stackexchange.com/questions/538631/multi-threaded-find-exec