find . -not -path './flash_drive_data*' | grep "./*flash*"
The thing here is that grep
uses regular expressions, while find -path
uses shell glob style pattern matches. The asterisk has a different meaning in those two.
The regular expression ./*flash*
matches first any character (.
), then zero or more slashes (/*
), then a literal string flas
, then any number (zero or more) of h
characters. 3/flas
matches that (with zero times h
), and so would e.g. reflash
(with zero times /
).
You could just use grep flash
instead, given that it matches anywhere in the input, so leading and tailing "match anything" parts are unnecessary.
Or use find -path './*flash*' -and -not -path './flash_drive_data*'
When I replaced grep "*flash*"
with just grep "*"
, I got [no matches].
Since the asterisk means "any number of the previous atom", it's not really well defined here. grep
interprets that as a literal asterisk, but really it should be an error.
However, when I ran: find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' +
I was getting output including things like:
./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/
so flash_drive_data
files were being included.
Note that tar
stores files recursively, and the first output of that find
is .
for the current directory, so everything will be stored. You may want to use ! -type d
with find
to exclude directories from the output, or (better), look at the -exclude=PATTERN
options to tar
.
Best Answer
In Unix-like systems, there are two output paths that if left unmodified will send output to your screen. Standard error (or stderr) is the one that captures most failures and error conditions.
To pass the permission denied message in the stderr to the same output stream as "regular output" you must combine the two. In your example, in order for your
grep -v
to properly operate on it, you combine stdout (standard output) and stderr with the arcane syntax you see.From GNU Bash manual section 3.2.2 Pipelines:
Also, as geirha points out, if you want to just get rid of stderr output, you would want to do something like
or perhaps
And note that if you have strings of commands, such as a
find
passing its output toxargs
you would need to put the entire pipeline of commands in parentheses to capture the output from all components of the command. E.g.,If you left out the parentheses, and did this instead --
you would still see permission denied errors from the find or egrep, but stderr would be redirected for xargs.
As you've seen, you would likely throw away the stderr only after viewing its contents during a test run.
Note that with GNU
find
and as far as I can tell, any POSIX-compliantfind
, the-print
option is implicit. You can still supply it explicitly if you like.