How can I find files in directories listed in a file?Find both regular files and directoriesDelete all files in directories except those whose path are listed in a fileFind directories without music filesTo count number of matches in a mega string quicklyMove all files from listed directories one level upFind command that excludes paths listed in a fileFind files inside numbered directoriesHow to find directories containing only specific files
How to determine algebraically whether an equation has an infinite solutions or not?
Notice period 60 days but I need to join in 45 days
Force SQL Server to use fragmented indexes?
How to pass 2>/dev/null as a variable?
Counting the triangles that can be formed from segments of given lengths
rationalizing sieges in a modern/near-future setting
Find feasible point in polynomial time in linear programming
Is there a word or phrase that means "use other people's wifi or Internet service without consent"?
What is the name of this plot that has rows with two connected dots?
Why is sh (not bash) complaining about functions defined in my .bashrc?
Are strlen optimizations really needed in glibc?
How to emphasise the insignificance of someone/thing – besides using "klein"
Is it true that different variants of the same model aircraft don't require pilot retraining?
Finding square root without division and initial guess
Why didn't Doc believe Marty was from the future?
Did ancient peoples ever hide their treasure behind puzzles?
Biological refrigeration?
Mathematica equivalent of a curl snippet
Is a memoized pure function itself considered pure?
Count the number of shortest paths to n
Does trying to charm an uncharmable creature cost a spell slot?
Term used to describe a person who predicts future outcomes
How to force GCC to assume that a floating-point expression is non-negative?
How much does Commander Data weigh?
How can I find files in directories listed in a file?
Find both regular files and directoriesDelete all files in directories except those whose path are listed in a fileFind directories without music filesTo count number of matches in a mega string quicklyMove all files from listed directories one level upFind command that excludes paths listed in a fileFind files inside numbered directoriesHow to find directories containing only specific files
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
In a directory there are several subdirectories, something like:
TopLevelDir
+-- SubDir1
+-- SubDir2
+-- SubDir3
+-- SubDir4
+-- SubDir5
+-- SubDir6
I need to find files containing some specific text in a specific subset of those subdirectories. What is needed can be accomplished with:
find SubDir1 SubDir2 SubDir4 -type f -exec grep -H "desired text" ;
A similar search will be needed frequently. To save time and typing, I would like to store the names of the subdirectories to be searched in a file and use that when I run the find command next time, something like:
find subdirs2search.txt -type f -name="*.txt" -exec grep -H "desired text" ;
Searching the web, checking man pages, and even checking my *nix book hasn't turned up anything on how to do this.
Is this possible? If so, how can it be done?
bash find directory-structure
add a comment |
In a directory there are several subdirectories, something like:
TopLevelDir
+-- SubDir1
+-- SubDir2
+-- SubDir3
+-- SubDir4
+-- SubDir5
+-- SubDir6
I need to find files containing some specific text in a specific subset of those subdirectories. What is needed can be accomplished with:
find SubDir1 SubDir2 SubDir4 -type f -exec grep -H "desired text" ;
A similar search will be needed frequently. To save time and typing, I would like to store the names of the subdirectories to be searched in a file and use that when I run the find command next time, something like:
find subdirs2search.txt -type f -name="*.txt" -exec grep -H "desired text" ;
Searching the web, checking man pages, and even checking my *nix book hasn't turned up anything on how to do this.
Is this possible? If so, how can it be done?
bash find directory-structure
2
If you used+to end the-execinstead of;, you wouldn't need the-Hoption on the grep command (it's the default if multiple file args are used). More importantly, it would also run noticeably faster because it wouldn't need to fork one grep per file (instead it would run grep with as many filename args as will fit on the command line).find SubDir1 SubDir2 SubDir4 -type f -exec grep "desired text" +
– cas
Aug 15 at 3:32
1
@cas: it's possible thatfindonly finds 1 regular file total, so-His still a good idea. But yes,-exec ... +is much faster than;especially for lots of small files where startup overhead matters more.
– Peter Cordes
Aug 15 at 5:31
@PeterCordes yes, that's true. i didn't think of that :)
– cas
Aug 15 at 5:43
add a comment |
In a directory there are several subdirectories, something like:
TopLevelDir
+-- SubDir1
+-- SubDir2
+-- SubDir3
+-- SubDir4
+-- SubDir5
+-- SubDir6
I need to find files containing some specific text in a specific subset of those subdirectories. What is needed can be accomplished with:
find SubDir1 SubDir2 SubDir4 -type f -exec grep -H "desired text" ;
A similar search will be needed frequently. To save time and typing, I would like to store the names of the subdirectories to be searched in a file and use that when I run the find command next time, something like:
find subdirs2search.txt -type f -name="*.txt" -exec grep -H "desired text" ;
Searching the web, checking man pages, and even checking my *nix book hasn't turned up anything on how to do this.
Is this possible? If so, how can it be done?
bash find directory-structure
In a directory there are several subdirectories, something like:
TopLevelDir
+-- SubDir1
+-- SubDir2
+-- SubDir3
+-- SubDir4
+-- SubDir5
+-- SubDir6
I need to find files containing some specific text in a specific subset of those subdirectories. What is needed can be accomplished with:
find SubDir1 SubDir2 SubDir4 -type f -exec grep -H "desired text" ;
A similar search will be needed frequently. To save time and typing, I would like to store the names of the subdirectories to be searched in a file and use that when I run the find command next time, something like:
find subdirs2search.txt -type f -name="*.txt" -exec grep -H "desired text" ;
Searching the web, checking man pages, and even checking my *nix book hasn't turned up anything on how to do this.
Is this possible? If so, how can it be done?
bash find directory-structure
bash find directory-structure
edited Aug 15 at 15:44
GreenMatt
asked Aug 14 at 20:00
GreenMattGreenMatt
4154 silver badges14 bronze badges
4154 silver badges14 bronze badges
2
If you used+to end the-execinstead of;, you wouldn't need the-Hoption on the grep command (it's the default if multiple file args are used). More importantly, it would also run noticeably faster because it wouldn't need to fork one grep per file (instead it would run grep with as many filename args as will fit on the command line).find SubDir1 SubDir2 SubDir4 -type f -exec grep "desired text" +
– cas
Aug 15 at 3:32
1
@cas: it's possible thatfindonly finds 1 regular file total, so-His still a good idea. But yes,-exec ... +is much faster than;especially for lots of small files where startup overhead matters more.
– Peter Cordes
Aug 15 at 5:31
@PeterCordes yes, that's true. i didn't think of that :)
– cas
Aug 15 at 5:43
add a comment |
2
If you used+to end the-execinstead of;, you wouldn't need the-Hoption on the grep command (it's the default if multiple file args are used). More importantly, it would also run noticeably faster because it wouldn't need to fork one grep per file (instead it would run grep with as many filename args as will fit on the command line).find SubDir1 SubDir2 SubDir4 -type f -exec grep "desired text" +
– cas
Aug 15 at 3:32
1
@cas: it's possible thatfindonly finds 1 regular file total, so-His still a good idea. But yes,-exec ... +is much faster than;especially for lots of small files where startup overhead matters more.
– Peter Cordes
Aug 15 at 5:31
@PeterCordes yes, that's true. i didn't think of that :)
– cas
Aug 15 at 5:43
2
2
If you used
+ to end the -exec instead of ;, you wouldn't need the -H option on the grep command (it's the default if multiple file args are used). More importantly, it would also run noticeably faster because it wouldn't need to fork one grep per file (instead it would run grep with as many filename args as will fit on the command line). find SubDir1 SubDir2 SubDir4 -type f -exec grep "desired text" +– cas
Aug 15 at 3:32
If you used
+ to end the -exec instead of ;, you wouldn't need the -H option on the grep command (it's the default if multiple file args are used). More importantly, it would also run noticeably faster because it wouldn't need to fork one grep per file (instead it would run grep with as many filename args as will fit on the command line). find SubDir1 SubDir2 SubDir4 -type f -exec grep "desired text" +– cas
Aug 15 at 3:32
1
1
@cas: it's possible that
find only finds 1 regular file total, so -H is still a good idea. But yes, -exec ... + is much faster than ; especially for lots of small files where startup overhead matters more.– Peter Cordes
Aug 15 at 5:31
@cas: it's possible that
find only finds 1 regular file total, so -H is still a good idea. But yes, -exec ... + is much faster than ; especially for lots of small files where startup overhead matters more.– Peter Cordes
Aug 15 at 5:31
@PeterCordes yes, that's true. i didn't think of that :)
– cas
Aug 15 at 5:43
@PeterCordes yes, that's true. i didn't think of that :)
– cas
Aug 15 at 5:43
add a comment |
5 Answers
5
active
oldest
votes
If the directory names are one-per-line, then you could avoid issues with directories that have spaces or tabs or wildcard characters in their names by using readarray (bash v4+):
readarray -t dirs < subdirs2search.txt
find "$dirs[@]" ...
That would still not help if some directory names start with -, but with GNU find, there's no way around that.
2
Prepending./to relative paths would ensure they're not parsed as options.
– John Kugelman
Aug 15 at 13:23
1
@John, unless they are full paths already (starting with/)
– Jeff Schaller♦
Aug 15 at 13:25
add a comment |
I found that it didn't limit the search to only text files
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files (determined using heuristics based on file name and content) and will by default skip directories like .git/.svn which if you're a developer is likely what you want. https://beyondgrep.com/.
It's packed by most GNU/Linux distros so it's easy to install. It's written in perl (so its regexps are perl regexps, similar to those of GNU grep -P).
ack -- "desired text" $(<subdirs.txt)
should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
(Different ways of word-splitting subdirs.txt onto a command line are covered in other answers. You might want to just let the shell's standard word-splitting do it, or readarray to split only on lines and also block glob expansion.)
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even withPERL_UNICODE=SLADwhich seems to only work for its--filter)
– Stéphane Chazelas
Aug 15 at 6:50
1
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text'helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).
– Stéphane Chazelas
Aug 15 at 7:09
add a comment |
Naturally, posting the question helped snap me out of my fixation on doing this strictly with find and made me think of expanding the file via Bash. I'm posting an answer hoping it will help someone else (and also to document this for my own future use).
The incantation for having Bash expand the file contents is $(<subdirs2search.txt). So, if subdirs2search.txt contains:
SubDir1 SubDir2 SubDir4
A command like the following will accomplish the desired search:
find $(<subdirs2search.txt) -type f -name="*.txt" -exec grep -H "desired text" ;
Note that it's not specific tobash. The$(<file)operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use$(cat file)instead.
– Stéphane Chazelas
Aug 14 at 21:02
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
1
"I found that it didn't limit the search to only text files", to be fair, neither does yourfindcommand.
– muru
Aug 15 at 5:30
2
@muru and Matt:ackis often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g.ack "desired text" $(<subdirs.txt)should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
– Peter Cordes
Aug 15 at 5:36
1
With grep, that's--include='*.txt'
– muru
Aug 15 at 15:46
|
show 9 more comments
Another tool similar to ack (Peter Cordes's answer) is ripgrep or rg. It supports the same usage:
rg -- "desired text" $(<subdirs2search.txt)
It also skips binary files by default.
add a comment |
#!/usr/bin/perl -w
use strict;
use File::Find ();
sub wanted;
sub process_file ($@);
my $dirfile = shift; # First argument is the filename containing the list
# of directories.
my $pattern = shift; # Second arg is a perl RE containing the pattern to search
# for. Remember to single-quote it on the command line.
# Read in the @dirs array from $dirfile
#
# A NUL-separated file is best, just in case any of the directory names
# contained line-feeds. If you're certain that could never happen, a
# plain-text LF-separated file would do.
#
# BTW, you can easily generate a NUL-separated file from the shell with:
# printf "%s" dir1 dir2 dir3 dir4 $'dirnwithn3nLFs' > dirs.txt
my @dirs=();
local $/=""; # delete this line if you want to use a LF-separated file.
# In that case, the ... block around the code from open to
# close is no longer needed. It's only there so it's possible
# to make a local change to the $/ aka $INPUT_RECORD_SEPARATOR
# variable.
open(DIRFILE,"<",$dirfile);
while(<DIRFILE>)
chomp;
push @dirs, $_;
;
close(DIRFILE);
;
File::Find::find(wanted => &wanted, @dirs);
exit;
sub wanted
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && process_file($_);
sub process_file ($@)
# This function currently just greps for pattern in the filename passed to
# it. As the function name implies, it could be used to process the file
# in any way, not just grep it.
my $filename = shift;
# uncomment the return statement below to skip "binary" files.
# (note this is a workable but fairly crude test. Perl's File::MMagic
# module can be used to more accurately identify file types, using the
# same "magic" file databases as the /usr/bin/file command)
# return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
print "$filename:$_" if (m/$pattern/o) ;
;
close(FILE);
This uses perl and perl's File::Find module to do the same thing as your find ... -exec grep.
There's nothing particularly interesting or special about this script except that the process_file function can be very easily modified to do anything you want with or to the file - e.g. change owner or perms, delete it, rename it, insert or delete lines or whatever else you might want.
e.g. if you wanted to delete files which contain text matching the pattern, you could replace the process_file function with something like this:
sub process_file ($@)
my $filename = shift;
my $found = 0;
# uncomment to skip "binary" files:
return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
if (m/$pattern/o)
$found = 1;
last;
;
;
close(FILE);
unlink $filename if ($found);
It's also worth mentioning that the wanted function in this script is currently only looking for regular files (the -f test). Perl's stat and lstat functions provide access to all of the file metadata that find can use to match files (uid, gid, perms, size, atime, mtime, etc) so the wanted function can replicate ANY and all find predicates. see perldoc -f stat and perldoc -f lstat for details.
BTW, the script was generated initially by find2perl, and then modified substantially to a) read in the list of directories from a file, and b) to do the grep in perl code rather than by forking grep and c) add a lot of comments. Performance should be nearly identical to find ... -exec grep because grep can't open files or do a regexp pattern match significantly faster than perl can. It may even be faster.
Also BTW, find2perl used to be included with perl, but since perl 5.22 it was removed and can now be found on CPAN at find2perl
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535634%2fhow-can-i-find-files-in-directories-listed-in-a-file%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
If the directory names are one-per-line, then you could avoid issues with directories that have spaces or tabs or wildcard characters in their names by using readarray (bash v4+):
readarray -t dirs < subdirs2search.txt
find "$dirs[@]" ...
That would still not help if some directory names start with -, but with GNU find, there's no way around that.
2
Prepending./to relative paths would ensure they're not parsed as options.
– John Kugelman
Aug 15 at 13:23
1
@John, unless they are full paths already (starting with/)
– Jeff Schaller♦
Aug 15 at 13:25
add a comment |
If the directory names are one-per-line, then you could avoid issues with directories that have spaces or tabs or wildcard characters in their names by using readarray (bash v4+):
readarray -t dirs < subdirs2search.txt
find "$dirs[@]" ...
That would still not help if some directory names start with -, but with GNU find, there's no way around that.
2
Prepending./to relative paths would ensure they're not parsed as options.
– John Kugelman
Aug 15 at 13:23
1
@John, unless they are full paths already (starting with/)
– Jeff Schaller♦
Aug 15 at 13:25
add a comment |
If the directory names are one-per-line, then you could avoid issues with directories that have spaces or tabs or wildcard characters in their names by using readarray (bash v4+):
readarray -t dirs < subdirs2search.txt
find "$dirs[@]" ...
That would still not help if some directory names start with -, but with GNU find, there's no way around that.
If the directory names are one-per-line, then you could avoid issues with directories that have spaces or tabs or wildcard characters in their names by using readarray (bash v4+):
readarray -t dirs < subdirs2search.txt
find "$dirs[@]" ...
That would still not help if some directory names start with -, but with GNU find, there's no way around that.
edited Aug 14 at 20:56
Stéphane Chazelas
331k58 gold badges648 silver badges1017 bronze badges
331k58 gold badges648 silver badges1017 bronze badges
answered Aug 14 at 20:23
Jeff Schaller♦Jeff Schaller
49.3k11 gold badges72 silver badges163 bronze badges
49.3k11 gold badges72 silver badges163 bronze badges
2
Prepending./to relative paths would ensure they're not parsed as options.
– John Kugelman
Aug 15 at 13:23
1
@John, unless they are full paths already (starting with/)
– Jeff Schaller♦
Aug 15 at 13:25
add a comment |
2
Prepending./to relative paths would ensure they're not parsed as options.
– John Kugelman
Aug 15 at 13:23
1
@John, unless they are full paths already (starting with/)
– Jeff Schaller♦
Aug 15 at 13:25
2
2
Prepending
./ to relative paths would ensure they're not parsed as options.– John Kugelman
Aug 15 at 13:23
Prepending
./ to relative paths would ensure they're not parsed as options.– John Kugelman
Aug 15 at 13:23
1
1
@John, unless they are full paths already (starting with
/)– Jeff Schaller♦
Aug 15 at 13:25
@John, unless they are full paths already (starting with
/)– Jeff Schaller♦
Aug 15 at 13:25
add a comment |
I found that it didn't limit the search to only text files
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files (determined using heuristics based on file name and content) and will by default skip directories like .git/.svn which if you're a developer is likely what you want. https://beyondgrep.com/.
It's packed by most GNU/Linux distros so it's easy to install. It's written in perl (so its regexps are perl regexps, similar to those of GNU grep -P).
ack -- "desired text" $(<subdirs.txt)
should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
(Different ways of word-splitting subdirs.txt onto a command line are covered in other answers. You might want to just let the shell's standard word-splitting do it, or readarray to split only on lines and also block glob expansion.)
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even withPERL_UNICODE=SLADwhich seems to only work for its--filter)
– Stéphane Chazelas
Aug 15 at 6:50
1
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text'helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).
– Stéphane Chazelas
Aug 15 at 7:09
add a comment |
I found that it didn't limit the search to only text files
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files (determined using heuristics based on file name and content) and will by default skip directories like .git/.svn which if you're a developer is likely what you want. https://beyondgrep.com/.
It's packed by most GNU/Linux distros so it's easy to install. It's written in perl (so its regexps are perl regexps, similar to those of GNU grep -P).
ack -- "desired text" $(<subdirs.txt)
should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
(Different ways of word-splitting subdirs.txt onto a command line are covered in other answers. You might want to just let the shell's standard word-splitting do it, or readarray to split only on lines and also block glob expansion.)
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even withPERL_UNICODE=SLADwhich seems to only work for its--filter)
– Stéphane Chazelas
Aug 15 at 6:50
1
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text'helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).
– Stéphane Chazelas
Aug 15 at 7:09
add a comment |
I found that it didn't limit the search to only text files
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files (determined using heuristics based on file name and content) and will by default skip directories like .git/.svn which if you're a developer is likely what you want. https://beyondgrep.com/.
It's packed by most GNU/Linux distros so it's easy to install. It's written in perl (so its regexps are perl regexps, similar to those of GNU grep -P).
ack -- "desired text" $(<subdirs.txt)
should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
(Different ways of word-splitting subdirs.txt onto a command line are covered in other answers. You might want to just let the shell's standard word-splitting do it, or readarray to split only on lines and also block glob expansion.)
I found that it didn't limit the search to only text files
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files (determined using heuristics based on file name and content) and will by default skip directories like .git/.svn which if you're a developer is likely what you want. https://beyondgrep.com/.
It's packed by most GNU/Linux distros so it's easy to install. It's written in perl (so its regexps are perl regexps, similar to those of GNU grep -P).
ack -- "desired text" $(<subdirs.txt)
should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
(Different ways of word-splitting subdirs.txt onto a command line are covered in other answers. You might want to just let the shell's standard word-splitting do it, or readarray to split only on lines and also block glob expansion.)
edited Aug 15 at 6:49
Stéphane Chazelas
331k58 gold badges648 silver badges1017 bronze badges
331k58 gold badges648 silver badges1017 bronze badges
answered Aug 15 at 5:38
Peter CordesPeter Cordes
4,73016 silver badges35 bronze badges
4,73016 silver badges35 bronze badges
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even withPERL_UNICODE=SLADwhich seems to only work for its--filter)
– Stéphane Chazelas
Aug 15 at 6:50
1
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text'helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).
– Stéphane Chazelas
Aug 15 at 7:09
add a comment |
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even withPERL_UNICODE=SLADwhich seems to only work for its--filter)
– Stéphane Chazelas
Aug 15 at 6:50
1
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text'helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).
– Stéphane Chazelas
Aug 15 at 7:09
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even with
PERL_UNICODE=SLAD which seems to only work for its --filter)– Stéphane Chazelas
Aug 15 at 6:50
Not the it only properly works with ASCII/ISO8859-1 data (not non-ASCII UTF-8 characters, even with
PERL_UNICODE=SLAD which seems to only work for its --filter)– Stéphane Chazelas
Aug 15 at 6:50
1
1
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text' helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).– Stéphane Chazelas
Aug 15 at 7:09
PERLIO=':utf8' PERL_UNICODE=A ack 'utf8 text' helps (though makes it significantly slower and reports decoding errors for non-UTF-8 input).– Stéphane Chazelas
Aug 15 at 7:09
add a comment |
Naturally, posting the question helped snap me out of my fixation on doing this strictly with find and made me think of expanding the file via Bash. I'm posting an answer hoping it will help someone else (and also to document this for my own future use).
The incantation for having Bash expand the file contents is $(<subdirs2search.txt). So, if subdirs2search.txt contains:
SubDir1 SubDir2 SubDir4
A command like the following will accomplish the desired search:
find $(<subdirs2search.txt) -type f -name="*.txt" -exec grep -H "desired text" ;
Note that it's not specific tobash. The$(<file)operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use$(cat file)instead.
– Stéphane Chazelas
Aug 14 at 21:02
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
1
"I found that it didn't limit the search to only text files", to be fair, neither does yourfindcommand.
– muru
Aug 15 at 5:30
2
@muru and Matt:ackis often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g.ack "desired text" $(<subdirs.txt)should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
– Peter Cordes
Aug 15 at 5:36
1
With grep, that's--include='*.txt'
– muru
Aug 15 at 15:46
|
show 9 more comments
Naturally, posting the question helped snap me out of my fixation on doing this strictly with find and made me think of expanding the file via Bash. I'm posting an answer hoping it will help someone else (and also to document this for my own future use).
The incantation for having Bash expand the file contents is $(<subdirs2search.txt). So, if subdirs2search.txt contains:
SubDir1 SubDir2 SubDir4
A command like the following will accomplish the desired search:
find $(<subdirs2search.txt) -type f -name="*.txt" -exec grep -H "desired text" ;
Note that it's not specific tobash. The$(<file)operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use$(cat file)instead.
– Stéphane Chazelas
Aug 14 at 21:02
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
1
"I found that it didn't limit the search to only text files", to be fair, neither does yourfindcommand.
– muru
Aug 15 at 5:30
2
@muru and Matt:ackis often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g.ack "desired text" $(<subdirs.txt)should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
– Peter Cordes
Aug 15 at 5:36
1
With grep, that's--include='*.txt'
– muru
Aug 15 at 15:46
|
show 9 more comments
Naturally, posting the question helped snap me out of my fixation on doing this strictly with find and made me think of expanding the file via Bash. I'm posting an answer hoping it will help someone else (and also to document this for my own future use).
The incantation for having Bash expand the file contents is $(<subdirs2search.txt). So, if subdirs2search.txt contains:
SubDir1 SubDir2 SubDir4
A command like the following will accomplish the desired search:
find $(<subdirs2search.txt) -type f -name="*.txt" -exec grep -H "desired text" ;
Naturally, posting the question helped snap me out of my fixation on doing this strictly with find and made me think of expanding the file via Bash. I'm posting an answer hoping it will help someone else (and also to document this for my own future use).
The incantation for having Bash expand the file contents is $(<subdirs2search.txt). So, if subdirs2search.txt contains:
SubDir1 SubDir2 SubDir4
A command like the following will accomplish the desired search:
find $(<subdirs2search.txt) -type f -name="*.txt" -exec grep -H "desired text" ;
edited Aug 15 at 15:43
answered Aug 14 at 20:09
GreenMattGreenMatt
4154 silver badges14 bronze badges
4154 silver badges14 bronze badges
Note that it's not specific tobash. The$(<file)operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use$(cat file)instead.
– Stéphane Chazelas
Aug 14 at 21:02
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
1
"I found that it didn't limit the search to only text files", to be fair, neither does yourfindcommand.
– muru
Aug 15 at 5:30
2
@muru and Matt:ackis often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g.ack "desired text" $(<subdirs.txt)should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
– Peter Cordes
Aug 15 at 5:36
1
With grep, that's--include='*.txt'
– muru
Aug 15 at 15:46
|
show 9 more comments
Note that it's not specific tobash. The$(<file)operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use$(cat file)instead.
– Stéphane Chazelas
Aug 14 at 21:02
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
1
"I found that it didn't limit the search to only text files", to be fair, neither does yourfindcommand.
– muru
Aug 15 at 5:30
2
@muru and Matt:ackis often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g.ack "desired text" $(<subdirs.txt)should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.
– Peter Cordes
Aug 15 at 5:36
1
With grep, that's--include='*.txt'
– muru
Aug 15 at 15:46
Note that it's not specific to
bash. The $(<file) operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use $(cat file) instead.– Stéphane Chazelas
Aug 14 at 21:02
Note that it's not specific to
bash. The $(<file) operator comes from ksh and is also supported by zsh. In other POSIX-like shells, you can use $(cat file) instead.– Stéphane Chazelas
Aug 14 at 21:02
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
@StéphaneChazelas: Thanks for the input. That said, I've rolled back to my original answer. Testing your solution, I found that it didn't limit the search to only text files, and it ran significantly slower. Also, it is different enough that - IMO - you should submit it as your own answer.
– GreenMatt
Aug 14 at 21:20
1
1
"I found that it didn't limit the search to only text files", to be fair, neither does your
find command.– muru
Aug 15 at 5:30
"I found that it didn't limit the search to only text files", to be fair, neither does your
find command.– muru
Aug 15 at 5:30
2
2
@muru and Matt:
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g. ack "desired text" $(<subdirs.txt) should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.– Peter Cordes
Aug 15 at 5:36
@muru and Matt:
ack is often a handy tool for recursive-grep type stuff. It does by default limit searching to text files. beyondgrep.com. It's packed by most GNU/Linux distros. e.g. ack "desired text" $(<subdirs.txt) should probably do what you want and is very easy to type. Plus it does nice color output for interactive use.– Peter Cordes
Aug 15 at 5:36
1
1
With grep, that's
--include='*.txt'– muru
Aug 15 at 15:46
With grep, that's
--include='*.txt'– muru
Aug 15 at 15:46
|
show 9 more comments
Another tool similar to ack (Peter Cordes's answer) is ripgrep or rg. It supports the same usage:
rg -- "desired text" $(<subdirs2search.txt)
It also skips binary files by default.
add a comment |
Another tool similar to ack (Peter Cordes's answer) is ripgrep or rg. It supports the same usage:
rg -- "desired text" $(<subdirs2search.txt)
It also skips binary files by default.
add a comment |
Another tool similar to ack (Peter Cordes's answer) is ripgrep or rg. It supports the same usage:
rg -- "desired text" $(<subdirs2search.txt)
It also skips binary files by default.
Another tool similar to ack (Peter Cordes's answer) is ripgrep or rg. It supports the same usage:
rg -- "desired text" $(<subdirs2search.txt)
It also skips binary files by default.
answered Aug 15 at 13:27
Mark AndersonMark Anderson
311 bronze badge
311 bronze badge
add a comment |
add a comment |
#!/usr/bin/perl -w
use strict;
use File::Find ();
sub wanted;
sub process_file ($@);
my $dirfile = shift; # First argument is the filename containing the list
# of directories.
my $pattern = shift; # Second arg is a perl RE containing the pattern to search
# for. Remember to single-quote it on the command line.
# Read in the @dirs array from $dirfile
#
# A NUL-separated file is best, just in case any of the directory names
# contained line-feeds. If you're certain that could never happen, a
# plain-text LF-separated file would do.
#
# BTW, you can easily generate a NUL-separated file from the shell with:
# printf "%s" dir1 dir2 dir3 dir4 $'dirnwithn3nLFs' > dirs.txt
my @dirs=();
local $/=""; # delete this line if you want to use a LF-separated file.
# In that case, the ... block around the code from open to
# close is no longer needed. It's only there so it's possible
# to make a local change to the $/ aka $INPUT_RECORD_SEPARATOR
# variable.
open(DIRFILE,"<",$dirfile);
while(<DIRFILE>)
chomp;
push @dirs, $_;
;
close(DIRFILE);
;
File::Find::find(wanted => &wanted, @dirs);
exit;
sub wanted
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && process_file($_);
sub process_file ($@)
# This function currently just greps for pattern in the filename passed to
# it. As the function name implies, it could be used to process the file
# in any way, not just grep it.
my $filename = shift;
# uncomment the return statement below to skip "binary" files.
# (note this is a workable but fairly crude test. Perl's File::MMagic
# module can be used to more accurately identify file types, using the
# same "magic" file databases as the /usr/bin/file command)
# return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
print "$filename:$_" if (m/$pattern/o) ;
;
close(FILE);
This uses perl and perl's File::Find module to do the same thing as your find ... -exec grep.
There's nothing particularly interesting or special about this script except that the process_file function can be very easily modified to do anything you want with or to the file - e.g. change owner or perms, delete it, rename it, insert or delete lines or whatever else you might want.
e.g. if you wanted to delete files which contain text matching the pattern, you could replace the process_file function with something like this:
sub process_file ($@)
my $filename = shift;
my $found = 0;
# uncomment to skip "binary" files:
return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
if (m/$pattern/o)
$found = 1;
last;
;
;
close(FILE);
unlink $filename if ($found);
It's also worth mentioning that the wanted function in this script is currently only looking for regular files (the -f test). Perl's stat and lstat functions provide access to all of the file metadata that find can use to match files (uid, gid, perms, size, atime, mtime, etc) so the wanted function can replicate ANY and all find predicates. see perldoc -f stat and perldoc -f lstat for details.
BTW, the script was generated initially by find2perl, and then modified substantially to a) read in the list of directories from a file, and b) to do the grep in perl code rather than by forking grep and c) add a lot of comments. Performance should be nearly identical to find ... -exec grep because grep can't open files or do a regexp pattern match significantly faster than perl can. It may even be faster.
Also BTW, find2perl used to be included with perl, but since perl 5.22 it was removed and can now be found on CPAN at find2perl
add a comment |
#!/usr/bin/perl -w
use strict;
use File::Find ();
sub wanted;
sub process_file ($@);
my $dirfile = shift; # First argument is the filename containing the list
# of directories.
my $pattern = shift; # Second arg is a perl RE containing the pattern to search
# for. Remember to single-quote it on the command line.
# Read in the @dirs array from $dirfile
#
# A NUL-separated file is best, just in case any of the directory names
# contained line-feeds. If you're certain that could never happen, a
# plain-text LF-separated file would do.
#
# BTW, you can easily generate a NUL-separated file from the shell with:
# printf "%s" dir1 dir2 dir3 dir4 $'dirnwithn3nLFs' > dirs.txt
my @dirs=();
local $/=""; # delete this line if you want to use a LF-separated file.
# In that case, the ... block around the code from open to
# close is no longer needed. It's only there so it's possible
# to make a local change to the $/ aka $INPUT_RECORD_SEPARATOR
# variable.
open(DIRFILE,"<",$dirfile);
while(<DIRFILE>)
chomp;
push @dirs, $_;
;
close(DIRFILE);
;
File::Find::find(wanted => &wanted, @dirs);
exit;
sub wanted
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && process_file($_);
sub process_file ($@)
# This function currently just greps for pattern in the filename passed to
# it. As the function name implies, it could be used to process the file
# in any way, not just grep it.
my $filename = shift;
# uncomment the return statement below to skip "binary" files.
# (note this is a workable but fairly crude test. Perl's File::MMagic
# module can be used to more accurately identify file types, using the
# same "magic" file databases as the /usr/bin/file command)
# return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
print "$filename:$_" if (m/$pattern/o) ;
;
close(FILE);
This uses perl and perl's File::Find module to do the same thing as your find ... -exec grep.
There's nothing particularly interesting or special about this script except that the process_file function can be very easily modified to do anything you want with or to the file - e.g. change owner or perms, delete it, rename it, insert or delete lines or whatever else you might want.
e.g. if you wanted to delete files which contain text matching the pattern, you could replace the process_file function with something like this:
sub process_file ($@)
my $filename = shift;
my $found = 0;
# uncomment to skip "binary" files:
return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
if (m/$pattern/o)
$found = 1;
last;
;
;
close(FILE);
unlink $filename if ($found);
It's also worth mentioning that the wanted function in this script is currently only looking for regular files (the -f test). Perl's stat and lstat functions provide access to all of the file metadata that find can use to match files (uid, gid, perms, size, atime, mtime, etc) so the wanted function can replicate ANY and all find predicates. see perldoc -f stat and perldoc -f lstat for details.
BTW, the script was generated initially by find2perl, and then modified substantially to a) read in the list of directories from a file, and b) to do the grep in perl code rather than by forking grep and c) add a lot of comments. Performance should be nearly identical to find ... -exec grep because grep can't open files or do a regexp pattern match significantly faster than perl can. It may even be faster.
Also BTW, find2perl used to be included with perl, but since perl 5.22 it was removed and can now be found on CPAN at find2perl
add a comment |
#!/usr/bin/perl -w
use strict;
use File::Find ();
sub wanted;
sub process_file ($@);
my $dirfile = shift; # First argument is the filename containing the list
# of directories.
my $pattern = shift; # Second arg is a perl RE containing the pattern to search
# for. Remember to single-quote it on the command line.
# Read in the @dirs array from $dirfile
#
# A NUL-separated file is best, just in case any of the directory names
# contained line-feeds. If you're certain that could never happen, a
# plain-text LF-separated file would do.
#
# BTW, you can easily generate a NUL-separated file from the shell with:
# printf "%s" dir1 dir2 dir3 dir4 $'dirnwithn3nLFs' > dirs.txt
my @dirs=();
local $/=""; # delete this line if you want to use a LF-separated file.
# In that case, the ... block around the code from open to
# close is no longer needed. It's only there so it's possible
# to make a local change to the $/ aka $INPUT_RECORD_SEPARATOR
# variable.
open(DIRFILE,"<",$dirfile);
while(<DIRFILE>)
chomp;
push @dirs, $_;
;
close(DIRFILE);
;
File::Find::find(wanted => &wanted, @dirs);
exit;
sub wanted
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && process_file($_);
sub process_file ($@)
# This function currently just greps for pattern in the filename passed to
# it. As the function name implies, it could be used to process the file
# in any way, not just grep it.
my $filename = shift;
# uncomment the return statement below to skip "binary" files.
# (note this is a workable but fairly crude test. Perl's File::MMagic
# module can be used to more accurately identify file types, using the
# same "magic" file databases as the /usr/bin/file command)
# return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
print "$filename:$_" if (m/$pattern/o) ;
;
close(FILE);
This uses perl and perl's File::Find module to do the same thing as your find ... -exec grep.
There's nothing particularly interesting or special about this script except that the process_file function can be very easily modified to do anything you want with or to the file - e.g. change owner or perms, delete it, rename it, insert or delete lines or whatever else you might want.
e.g. if you wanted to delete files which contain text matching the pattern, you could replace the process_file function with something like this:
sub process_file ($@)
my $filename = shift;
my $found = 0;
# uncomment to skip "binary" files:
return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
if (m/$pattern/o)
$found = 1;
last;
;
;
close(FILE);
unlink $filename if ($found);
It's also worth mentioning that the wanted function in this script is currently only looking for regular files (the -f test). Perl's stat and lstat functions provide access to all of the file metadata that find can use to match files (uid, gid, perms, size, atime, mtime, etc) so the wanted function can replicate ANY and all find predicates. see perldoc -f stat and perldoc -f lstat for details.
BTW, the script was generated initially by find2perl, and then modified substantially to a) read in the list of directories from a file, and b) to do the grep in perl code rather than by forking grep and c) add a lot of comments. Performance should be nearly identical to find ... -exec grep because grep can't open files or do a regexp pattern match significantly faster than perl can. It may even be faster.
Also BTW, find2perl used to be included with perl, but since perl 5.22 it was removed and can now be found on CPAN at find2perl
#!/usr/bin/perl -w
use strict;
use File::Find ();
sub wanted;
sub process_file ($@);
my $dirfile = shift; # First argument is the filename containing the list
# of directories.
my $pattern = shift; # Second arg is a perl RE containing the pattern to search
# for. Remember to single-quote it on the command line.
# Read in the @dirs array from $dirfile
#
# A NUL-separated file is best, just in case any of the directory names
# contained line-feeds. If you're certain that could never happen, a
# plain-text LF-separated file would do.
#
# BTW, you can easily generate a NUL-separated file from the shell with:
# printf "%s" dir1 dir2 dir3 dir4 $'dirnwithn3nLFs' > dirs.txt
my @dirs=();
local $/=""; # delete this line if you want to use a LF-separated file.
# In that case, the ... block around the code from open to
# close is no longer needed. It's only there so it's possible
# to make a local change to the $/ aka $INPUT_RECORD_SEPARATOR
# variable.
open(DIRFILE,"<",$dirfile);
while(<DIRFILE>)
chomp;
push @dirs, $_;
;
close(DIRFILE);
;
File::Find::find(wanted => &wanted, @dirs);
exit;
sub wanted
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && process_file($_);
sub process_file ($@)
# This function currently just greps for pattern in the filename passed to
# it. As the function name implies, it could be used to process the file
# in any way, not just grep it.
my $filename = shift;
# uncomment the return statement below to skip "binary" files.
# (note this is a workable but fairly crude test. Perl's File::MMagic
# module can be used to more accurately identify file types, using the
# same "magic" file databases as the /usr/bin/file command)
# return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
print "$filename:$_" if (m/$pattern/o) ;
;
close(FILE);
This uses perl and perl's File::Find module to do the same thing as your find ... -exec grep.
There's nothing particularly interesting or special about this script except that the process_file function can be very easily modified to do anything you want with or to the file - e.g. change owner or perms, delete it, rename it, insert or delete lines or whatever else you might want.
e.g. if you wanted to delete files which contain text matching the pattern, you could replace the process_file function with something like this:
sub process_file ($@)
my $filename = shift;
my $found = 0;
# uncomment to skip "binary" files:
return if -B $filename;
open(FILE,"<",$filename);
while(<FILE>)
if (m/$pattern/o)
$found = 1;
last;
;
;
close(FILE);
unlink $filename if ($found);
It's also worth mentioning that the wanted function in this script is currently only looking for regular files (the -f test). Perl's stat and lstat functions provide access to all of the file metadata that find can use to match files (uid, gid, perms, size, atime, mtime, etc) so the wanted function can replicate ANY and all find predicates. see perldoc -f stat and perldoc -f lstat for details.
BTW, the script was generated initially by find2perl, and then modified substantially to a) read in the list of directories from a file, and b) to do the grep in perl code rather than by forking grep and c) add a lot of comments. Performance should be nearly identical to find ... -exec grep because grep can't open files or do a regexp pattern match significantly faster than perl can. It may even be faster.
Also BTW, find2perl used to be included with perl, but since perl 5.22 it was removed and can now be found on CPAN at find2perl
edited Aug 17 at 2:03
answered Aug 15 at 4:47
cascas
42.1k4 gold badges62 silver badges112 bronze badges
42.1k4 gold badges62 silver badges112 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535634%2fhow-can-i-find-files-in-directories-listed-in-a-file%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
If you used
+to end the-execinstead of;, you wouldn't need the-Hoption on the grep command (it's the default if multiple file args are used). More importantly, it would also run noticeably faster because it wouldn't need to fork one grep per file (instead it would run grep with as many filename args as will fit on the command line).find SubDir1 SubDir2 SubDir4 -type f -exec grep "desired text" +– cas
Aug 15 at 3:32
1
@cas: it's possible that
findonly finds 1 regular file total, so-His still a good idea. But yes,-exec ... +is much faster than;especially for lots of small files where startup overhead matters more.– Peter Cordes
Aug 15 at 5:31
@PeterCordes yes, that's true. i didn't think of that :)
– cas
Aug 15 at 5:43