`find` with multiple `-name` and `-exec` executes only the last matches of `-name`

Clash Royale CLAN TAG#URR8PPP
up vote
54
down vote
favorite
When I'm using
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
it finds all the types of file. But when I add -exec at the end:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' ;
it seems it only prints .txt files. What am I doing wrong?
Note: using MINGW (Git Bash)
find
add a comment |Â
up vote
54
down vote
favorite
When I'm using
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
it finds all the types of file. But when I add -exec at the end:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' ;
it seems it only prints .txt files. What am I doing wrong?
Note: using MINGW (Git Bash)
find
Hint: the first command will also print directories whose names match*.js*or*.txt.
â Wildcard
Sep 8 '17 at 0:00
add a comment |Â
up vote
54
down vote
favorite
up vote
54
down vote
favorite
When I'm using
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
it finds all the types of file. But when I add -exec at the end:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' ;
it seems it only prints .txt files. What am I doing wrong?
Note: using MINGW (Git Bash)
find
When I'm using
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
it finds all the types of file. But when I add -exec at the end:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' ;
it seems it only prints .txt files. What am I doing wrong?
Note: using MINGW (Git Bash)
find
find
asked Nov 22 '13 at 10:52
jakub.g
91621015
91621015
Hint: the first command will also print directories whose names match*.js*or*.txt.
â Wildcard
Sep 8 '17 at 0:00
add a comment |Â
Hint: the first command will also print directories whose names match*.js*or*.txt.
â Wildcard
Sep 8 '17 at 0:00
Hint: the first command will also print directories whose names match
*.js* or *.txt.â Wildcard
Sep 8 '17 at 0:00
Hint: the first command will also print directories whose names match
*.js* or *.txt.â Wildcard
Sep 8 '17 at 0:00
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
75
down vote
accepted
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
is short for:
find . ( ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" )
) -a -print
That is, because no action predicate is specified (only conditions), a -print action is implicitly added for the files that match the conditions.
(and, by the way, that would print non-regular .js files (the -type f only applies to .htm files)).
While:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
-exec sh -c 'echo "$0"' ;
is short for:
find . ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" -a -exec sh -c 'echo "$0"' ; )
For find (like in many languages), AND (-a; implicit when omitted) has precedence over OR (-o), and adding an explicit action predicate (here -exec) cancels the -print implicit action seen above. Here, you want:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" )
-exec sh -c 'echo "$0"' ;
Or:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c '
for i do
echo "$i"
done' sh +
To avoid running one sh per file.
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
That's a great answer!
â Marinos An
Feb 28 at 21:05
add a comment |Â
up vote
22
down vote
It is the implied brackets. Add explicit brackets. ( )
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c 'echo "$0"' ;
or using xargs ( I like xargs I find it easier, but apparently not as portable).
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -print0 | xargs -0 -n1 echo
add a comment |Â
up vote
0
down vote
Remember you can always add the "&&" like below...
find -name "*.html" && find -name "*.js" && find -name "*.txt"
2
This does not answer the question as there's no-execaction. Also, running multiplefindcommands to traverse the same directory tree is inefficient.
â Anthony Geoghegan
Sep 12 at 8:35
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
75
down vote
accepted
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
is short for:
find . ( ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" )
) -a -print
That is, because no action predicate is specified (only conditions), a -print action is implicitly added for the files that match the conditions.
(and, by the way, that would print non-regular .js files (the -type f only applies to .htm files)).
While:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
-exec sh -c 'echo "$0"' ;
is short for:
find . ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" -a -exec sh -c 'echo "$0"' ; )
For find (like in many languages), AND (-a; implicit when omitted) has precedence over OR (-o), and adding an explicit action predicate (here -exec) cancels the -print implicit action seen above. Here, you want:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" )
-exec sh -c 'echo "$0"' ;
Or:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c '
for i do
echo "$i"
done' sh +
To avoid running one sh per file.
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
That's a great answer!
â Marinos An
Feb 28 at 21:05
add a comment |Â
up vote
75
down vote
accepted
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
is short for:
find . ( ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" )
) -a -print
That is, because no action predicate is specified (only conditions), a -print action is implicitly added for the files that match the conditions.
(and, by the way, that would print non-regular .js files (the -type f only applies to .htm files)).
While:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
-exec sh -c 'echo "$0"' ;
is short for:
find . ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" -a -exec sh -c 'echo "$0"' ; )
For find (like in many languages), AND (-a; implicit when omitted) has precedence over OR (-o), and adding an explicit action predicate (here -exec) cancels the -print implicit action seen above. Here, you want:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" )
-exec sh -c 'echo "$0"' ;
Or:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c '
for i do
echo "$i"
done' sh +
To avoid running one sh per file.
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
That's a great answer!
â Marinos An
Feb 28 at 21:05
add a comment |Â
up vote
75
down vote
accepted
up vote
75
down vote
accepted
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
is short for:
find . ( ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" )
) -a -print
That is, because no action predicate is specified (only conditions), a -print action is implicitly added for the files that match the conditions.
(and, by the way, that would print non-regular .js files (the -type f only applies to .htm files)).
While:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
-exec sh -c 'echo "$0"' ;
is short for:
find . ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" -a -exec sh -c 'echo "$0"' ; )
For find (like in many languages), AND (-a; implicit when omitted) has precedence over OR (-o), and adding an explicit action predicate (here -exec) cancels the -print implicit action seen above. Here, you want:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" )
-exec sh -c 'echo "$0"' ;
Or:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c '
for i do
echo "$i"
done' sh +
To avoid running one sh per file.
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
is short for:
find . ( ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" )
) -a -print
That is, because no action predicate is specified (only conditions), a -print action is implicitly added for the files that match the conditions.
(and, by the way, that would print non-regular .js files (the -type f only applies to .htm files)).
While:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
-exec sh -c 'echo "$0"' ;
is short for:
find . ( -type f -a -name "*.htm*" ) -o
( -name "*.js*" ) -o
( -name "*.txt" -a -exec sh -c 'echo "$0"' ; )
For find (like in many languages), AND (-a; implicit when omitted) has precedence over OR (-o), and adding an explicit action predicate (here -exec) cancels the -print implicit action seen above. Here, you want:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" )
-exec sh -c 'echo "$0"' ;
Or:
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c '
for i do
echo "$i"
done' sh +
To avoid running one sh per file.
edited 14 mins ago
answered Nov 22 '13 at 12:34
Stéphane Chazelas
292k54544884
292k54544884
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
That's a great answer!
â Marinos An
Feb 28 at 21:05
add a comment |Â
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
That's a great answer!
â Marinos An
Feb 28 at 21:05
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
In some of those sh -c uses, you need to add the zeroth argument for sh (though in others you included it already).
â James Youngman
Dec 9 '13 at 23:14
That's a great answer!
â Marinos An
Feb 28 at 21:05
That's a great answer!
â Marinos An
Feb 28 at 21:05
add a comment |Â
up vote
22
down vote
It is the implied brackets. Add explicit brackets. ( )
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c 'echo "$0"' ;
or using xargs ( I like xargs I find it easier, but apparently not as portable).
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -print0 | xargs -0 -n1 echo
add a comment |Â
up vote
22
down vote
It is the implied brackets. Add explicit brackets. ( )
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c 'echo "$0"' ;
or using xargs ( I like xargs I find it easier, but apparently not as portable).
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -print0 | xargs -0 -n1 echo
add a comment |Â
up vote
22
down vote
up vote
22
down vote
It is the implied brackets. Add explicit brackets. ( )
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c 'echo "$0"' ;
or using xargs ( I like xargs I find it easier, but apparently not as portable).
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -print0 | xargs -0 -n1 echo
It is the implied brackets. Add explicit brackets. ( )
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -exec sh -c 'echo "$0"' ;
or using xargs ( I like xargs I find it easier, but apparently not as portable).
find . -type f ( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ) -print0 | xargs -0 -n1 echo
edited Jul 1 '14 at 10:14
answered Nov 22 '13 at 11:31
ctrl-alt-delor
9,60331950
9,60331950
add a comment |Â
add a comment |Â
up vote
0
down vote
Remember you can always add the "&&" like below...
find -name "*.html" && find -name "*.js" && find -name "*.txt"
2
This does not answer the question as there's no-execaction. Also, running multiplefindcommands to traverse the same directory tree is inefficient.
â Anthony Geoghegan
Sep 12 at 8:35
add a comment |Â
up vote
0
down vote
Remember you can always add the "&&" like below...
find -name "*.html" && find -name "*.js" && find -name "*.txt"
2
This does not answer the question as there's no-execaction. Also, running multiplefindcommands to traverse the same directory tree is inefficient.
â Anthony Geoghegan
Sep 12 at 8:35
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Remember you can always add the "&&" like below...
find -name "*.html" && find -name "*.js" && find -name "*.txt"
Remember you can always add the "&&" like below...
find -name "*.html" && find -name "*.js" && find -name "*.txt"
answered Sep 12 at 8:20
kierzo
1
1
2
This does not answer the question as there's no-execaction. Also, running multiplefindcommands to traverse the same directory tree is inefficient.
â Anthony Geoghegan
Sep 12 at 8:35
add a comment |Â
2
This does not answer the question as there's no-execaction. Also, running multiplefindcommands to traverse the same directory tree is inefficient.
â Anthony Geoghegan
Sep 12 at 8:35
2
2
This does not answer the question as there's no
-exec action. Also, running multiple find commands to traverse the same directory tree is inefficient.â Anthony Geoghegan
Sep 12 at 8:35
This does not answer the question as there's no
-exec action. Also, running multiple find commands to traverse the same directory tree is inefficient.â Anthony Geoghegan
Sep 12 at 8:35
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f102191%2ffind-with-multiple-name-and-exec-executes-only-the-last-matches-of-nam%23new-answer', 'question_page');
);
Post as a guest
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
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
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
Hint: the first command will also print directories whose names match
*.js*or*.txt.â Wildcard
Sep 8 '17 at 0:00