Given two patterns, search specific directories and print last three file names that match each pattern
Clash Royale CLAN TAG#URR8PPP
up vote
4
down vote
favorite
How can I shorten this command? The goal is to display the latest 3 files that are in the ABC
folder and match uvw
in the file name, then do the same but match xyz
in the file name.
I'm looking to shorten this since there's a need to add more strings to look for in the future.
find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3; find . -name 'ABC' | xargs ls | grep -i xyz |sort| tail -n 3
Example output:
2018-06-23T01-23-56.919Z-UVW.gz
2018-06-23T01-29-56.556Z-UVW.gz
2018-06-23T23-26-14.463Z-UVW.gz
2018-08-08T00-16-22.923Z-xyz.js
2018-08-08T00-16-24.517Z-xyz.js
2018-08-08T00-16-25.427Z-xyz.js
linux files find wildcards
add a comment |Â
up vote
4
down vote
favorite
How can I shorten this command? The goal is to display the latest 3 files that are in the ABC
folder and match uvw
in the file name, then do the same but match xyz
in the file name.
I'm looking to shorten this since there's a need to add more strings to look for in the future.
find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3; find . -name 'ABC' | xargs ls | grep -i xyz |sort| tail -n 3
Example output:
2018-06-23T01-23-56.919Z-UVW.gz
2018-06-23T01-29-56.556Z-UVW.gz
2018-06-23T23-26-14.463Z-UVW.gz
2018-08-08T00-16-22.923Z-xyz.js
2018-08-08T00-16-24.517Z-xyz.js
2018-08-08T00-16-25.427Z-xyz.js
linux files find wildcards
@don_crissti is correct. I edited my question to clarify this.
â kouichi
Aug 8 at 18:40
@steeldriver, the xargs runs ls on all the folders with the name ABC in them.
â kouichi
Aug 8 at 18:41
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
How can I shorten this command? The goal is to display the latest 3 files that are in the ABC
folder and match uvw
in the file name, then do the same but match xyz
in the file name.
I'm looking to shorten this since there's a need to add more strings to look for in the future.
find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3; find . -name 'ABC' | xargs ls | grep -i xyz |sort| tail -n 3
Example output:
2018-06-23T01-23-56.919Z-UVW.gz
2018-06-23T01-29-56.556Z-UVW.gz
2018-06-23T23-26-14.463Z-UVW.gz
2018-08-08T00-16-22.923Z-xyz.js
2018-08-08T00-16-24.517Z-xyz.js
2018-08-08T00-16-25.427Z-xyz.js
linux files find wildcards
How can I shorten this command? The goal is to display the latest 3 files that are in the ABC
folder and match uvw
in the file name, then do the same but match xyz
in the file name.
I'm looking to shorten this since there's a need to add more strings to look for in the future.
find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3; find . -name 'ABC' | xargs ls | grep -i xyz |sort| tail -n 3
Example output:
2018-06-23T01-23-56.919Z-UVW.gz
2018-06-23T01-29-56.556Z-UVW.gz
2018-06-23T23-26-14.463Z-UVW.gz
2018-08-08T00-16-22.923Z-xyz.js
2018-08-08T00-16-24.517Z-xyz.js
2018-08-08T00-16-25.427Z-xyz.js
linux files find wildcards
edited Aug 8 at 19:10
don_crissti
46.4k15123152
46.4k15123152
asked Aug 8 at 18:18
kouichi
315
315
@don_crissti is correct. I edited my question to clarify this.
â kouichi
Aug 8 at 18:40
@steeldriver, the xargs runs ls on all the folders with the name ABC in them.
â kouichi
Aug 8 at 18:41
add a comment |Â
@don_crissti is correct. I edited my question to clarify this.
â kouichi
Aug 8 at 18:40
@steeldriver, the xargs runs ls on all the folders with the name ABC in them.
â kouichi
Aug 8 at 18:41
@don_crissti is correct. I edited my question to clarify this.
â kouichi
Aug 8 at 18:40
@don_crissti is correct. I edited my question to clarify this.
â kouichi
Aug 8 at 18:40
@steeldriver, the xargs runs ls on all the folders with the name ABC in them.
â kouichi
Aug 8 at 18:41
@steeldriver, the xargs runs ls on all the folders with the name ABC in them.
â kouichi
Aug 8 at 18:41
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
4
down vote
With zsh
:
set -o extendedglob # best in ~/.zshrc
for w (uvw xyz) printf '%sn' **/ABC/(#i)*$w*(D[-3,-1]:t)
**/
: any level of subdirectories(#i)
: case insensitive matching for what follows(D[-3,-1]:t)
: glob qualifierD
: include hidden files and look inside hidden dirs likefind
does[-3,-1]
: select only the last 3 (globs are sorted in lexical order by default):t
: modifier that extracts the tail of the file path (basename) like yourls
does.
Note that if there are several ABC directories, the name of those directories will influence the sorting (files in a/ABC
will appear before those in b/ABC
).
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
add a comment |Â
up vote
2
down vote
This will search for any files which match any of those fragments:
for fragment in ABC UVW xyz; do
find . -name "*$fragment*" | sort | tail -n3;
done
If you want to find files which match all of them, you can do something like this:
find . -name '*ABC*' -a -name '*xyz*' | sort | tail -n3
-a
is find
's boolean AND operator.
For BSD find
, use -or
and -and
rather than -o
and -a
.
2
-a
is the implicit default between thefind
tests.
â Kusalananda
Aug 8 at 18:36
1
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
add a comment |Â
up vote
2
down vote
Most probably you are looking for
find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3
Here's how it works:
-iregex
search in case insensitive mode.*/ABC/
look in any depth for directory ABC (the whole name of dir)[^/]*uvw.*
the name of dirABC
is directly followed by a filename containinguvw
string, not any sub-directories in between
The sort
and tail
parts are untouched.
As for adding other patterns: you need to make a loop over this command with all needed strings, or if you need only 3 files regardless from which group they are coming you can combine everything in one command:
find . -iregex '.*/ABC/[^/]*(uvw|xyz)[^/]*' | sort | tail -n3
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
add a comment |Â
up vote
1
down vote
I got what I needed with for loops in a bash script, is it possible to do this in the command line?
#!/bin/bash
for i in ABC DEF
do
for j in uvw xyz
do
x=`find . -iname $i | xargs ls | grep -i $j | sort | tail -n 3`
echo "$x"
done
done
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
With zsh
:
set -o extendedglob # best in ~/.zshrc
for w (uvw xyz) printf '%sn' **/ABC/(#i)*$w*(D[-3,-1]:t)
**/
: any level of subdirectories(#i)
: case insensitive matching for what follows(D[-3,-1]:t)
: glob qualifierD
: include hidden files and look inside hidden dirs likefind
does[-3,-1]
: select only the last 3 (globs are sorted in lexical order by default):t
: modifier that extracts the tail of the file path (basename) like yourls
does.
Note that if there are several ABC directories, the name of those directories will influence the sorting (files in a/ABC
will appear before those in b/ABC
).
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
add a comment |Â
up vote
4
down vote
With zsh
:
set -o extendedglob # best in ~/.zshrc
for w (uvw xyz) printf '%sn' **/ABC/(#i)*$w*(D[-3,-1]:t)
**/
: any level of subdirectories(#i)
: case insensitive matching for what follows(D[-3,-1]:t)
: glob qualifierD
: include hidden files and look inside hidden dirs likefind
does[-3,-1]
: select only the last 3 (globs are sorted in lexical order by default):t
: modifier that extracts the tail of the file path (basename) like yourls
does.
Note that if there are several ABC directories, the name of those directories will influence the sorting (files in a/ABC
will appear before those in b/ABC
).
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
add a comment |Â
up vote
4
down vote
up vote
4
down vote
With zsh
:
set -o extendedglob # best in ~/.zshrc
for w (uvw xyz) printf '%sn' **/ABC/(#i)*$w*(D[-3,-1]:t)
**/
: any level of subdirectories(#i)
: case insensitive matching for what follows(D[-3,-1]:t)
: glob qualifierD
: include hidden files and look inside hidden dirs likefind
does[-3,-1]
: select only the last 3 (globs are sorted in lexical order by default):t
: modifier that extracts the tail of the file path (basename) like yourls
does.
Note that if there are several ABC directories, the name of those directories will influence the sorting (files in a/ABC
will appear before those in b/ABC
).
With zsh
:
set -o extendedglob # best in ~/.zshrc
for w (uvw xyz) printf '%sn' **/ABC/(#i)*$w*(D[-3,-1]:t)
**/
: any level of subdirectories(#i)
: case insensitive matching for what follows(D[-3,-1]:t)
: glob qualifierD
: include hidden files and look inside hidden dirs likefind
does[-3,-1]
: select only the last 3 (globs are sorted in lexical order by default):t
: modifier that extracts the tail of the file path (basename) like yourls
does.
Note that if there are several ABC directories, the name of those directories will influence the sorting (files in a/ABC
will appear before those in b/ABC
).
edited Aug 8 at 19:05
answered Aug 8 at 19:00
Stéphane Chazelas
280k53514846
280k53514846
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
add a comment |Â
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
Is this a bash command? I'm getting this error: -bash: set: extendedglob: invalid option name
â kouichi
Aug 8 at 20:49
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
@kouichi, no, it's zsh syntax, not bash, it says at the start of the answer.
â Stéphane Chazelas
Aug 8 at 21:37
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
Thanks, I have no idea how zsh works but I made a bash script which fits what I need
â kouichi
Aug 8 at 23:07
add a comment |Â
up vote
2
down vote
This will search for any files which match any of those fragments:
for fragment in ABC UVW xyz; do
find . -name "*$fragment*" | sort | tail -n3;
done
If you want to find files which match all of them, you can do something like this:
find . -name '*ABC*' -a -name '*xyz*' | sort | tail -n3
-a
is find
's boolean AND operator.
For BSD find
, use -or
and -and
rather than -o
and -a
.
2
-a
is the implicit default between thefind
tests.
â Kusalananda
Aug 8 at 18:36
1
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
add a comment |Â
up vote
2
down vote
This will search for any files which match any of those fragments:
for fragment in ABC UVW xyz; do
find . -name "*$fragment*" | sort | tail -n3;
done
If you want to find files which match all of them, you can do something like this:
find . -name '*ABC*' -a -name '*xyz*' | sort | tail -n3
-a
is find
's boolean AND operator.
For BSD find
, use -or
and -and
rather than -o
and -a
.
2
-a
is the implicit default between thefind
tests.
â Kusalananda
Aug 8 at 18:36
1
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
add a comment |Â
up vote
2
down vote
up vote
2
down vote
This will search for any files which match any of those fragments:
for fragment in ABC UVW xyz; do
find . -name "*$fragment*" | sort | tail -n3;
done
If you want to find files which match all of them, you can do something like this:
find . -name '*ABC*' -a -name '*xyz*' | sort | tail -n3
-a
is find
's boolean AND operator.
For BSD find
, use -or
and -and
rather than -o
and -a
.
This will search for any files which match any of those fragments:
for fragment in ABC UVW xyz; do
find . -name "*$fragment*" | sort | tail -n3;
done
If you want to find files which match all of them, you can do something like this:
find . -name '*ABC*' -a -name '*xyz*' | sort | tail -n3
-a
is find
's boolean AND operator.
For BSD find
, use -or
and -and
rather than -o
and -a
.
edited Aug 8 at 18:38
answered Aug 8 at 18:26
DopeGhoti
40.1k54779
40.1k54779
2
-a
is the implicit default between thefind
tests.
â Kusalananda
Aug 8 at 18:36
1
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
add a comment |Â
2
-a
is the implicit default between thefind
tests.
â Kusalananda
Aug 8 at 18:36
1
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
2
2
-a
is the implicit default between the find
tests.â Kusalananda
Aug 8 at 18:36
-a
is the implicit default between the find
tests.â Kusalananda
Aug 8 at 18:36
1
1
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Yes, but I prefer to be explicit when possible to prevent possible misreading by future-me.
â DopeGhoti
Aug 8 at 18:37
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
Not sure who upvoted here but anyway, please read the question again and revise your post.
â don_crissti
Aug 8 at 19:15
add a comment |Â
up vote
2
down vote
Most probably you are looking for
find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3
Here's how it works:
-iregex
search in case insensitive mode.*/ABC/
look in any depth for directory ABC (the whole name of dir)[^/]*uvw.*
the name of dirABC
is directly followed by a filename containinguvw
string, not any sub-directories in between
The sort
and tail
parts are untouched.
As for adding other patterns: you need to make a loop over this command with all needed strings, or if you need only 3 files regardless from which group they are coming you can combine everything in one command:
find . -iregex '.*/ABC/[^/]*(uvw|xyz)[^/]*' | sort | tail -n3
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
add a comment |Â
up vote
2
down vote
Most probably you are looking for
find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3
Here's how it works:
-iregex
search in case insensitive mode.*/ABC/
look in any depth for directory ABC (the whole name of dir)[^/]*uvw.*
the name of dirABC
is directly followed by a filename containinguvw
string, not any sub-directories in between
The sort
and tail
parts are untouched.
As for adding other patterns: you need to make a loop over this command with all needed strings, or if you need only 3 files regardless from which group they are coming you can combine everything in one command:
find . -iregex '.*/ABC/[^/]*(uvw|xyz)[^/]*' | sort | tail -n3
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Most probably you are looking for
find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3
Here's how it works:
-iregex
search in case insensitive mode.*/ABC/
look in any depth for directory ABC (the whole name of dir)[^/]*uvw.*
the name of dirABC
is directly followed by a filename containinguvw
string, not any sub-directories in between
The sort
and tail
parts are untouched.
As for adding other patterns: you need to make a loop over this command with all needed strings, or if you need only 3 files regardless from which group they are coming you can combine everything in one command:
find . -iregex '.*/ABC/[^/]*(uvw|xyz)[^/]*' | sort | tail -n3
Most probably you are looking for
find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3
Here's how it works:
-iregex
search in case insensitive mode.*/ABC/
look in any depth for directory ABC (the whole name of dir)[^/]*uvw.*
the name of dirABC
is directly followed by a filename containinguvw
string, not any sub-directories in between
The sort
and tail
parts are untouched.
As for adding other patterns: you need to make a loop over this command with all needed strings, or if you need only 3 files regardless from which group they are coming you can combine everything in one command:
find . -iregex '.*/ABC/[^/]*(uvw|xyz)[^/]*' | sort | tail -n3
edited Aug 8 at 19:35
answered Aug 8 at 19:17
jimmij
28.8k86699
28.8k86699
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
add a comment |Â
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
Thanks @jimmij. 'It looks like find . -iregex '.*/ABC/[^/]*uvw.*' | sort | tail -n3' is similar to 'find . -name 'ABC' | xargs ls | grep -i uvw |sort| tail -n 3', but takes longer to search. Maybe I can loop over ABC, DEF, etc. like what you've mentioned. I'll give it a try
â kouichi
Aug 8 at 20:55
add a comment |Â
up vote
1
down vote
I got what I needed with for loops in a bash script, is it possible to do this in the command line?
#!/bin/bash
for i in ABC DEF
do
for j in uvw xyz
do
x=`find . -iname $i | xargs ls | grep -i $j | sort | tail -n 3`
echo "$x"
done
done
add a comment |Â
up vote
1
down vote
I got what I needed with for loops in a bash script, is it possible to do this in the command line?
#!/bin/bash
for i in ABC DEF
do
for j in uvw xyz
do
x=`find . -iname $i | xargs ls | grep -i $j | sort | tail -n 3`
echo "$x"
done
done
add a comment |Â
up vote
1
down vote
up vote
1
down vote
I got what I needed with for loops in a bash script, is it possible to do this in the command line?
#!/bin/bash
for i in ABC DEF
do
for j in uvw xyz
do
x=`find . -iname $i | xargs ls | grep -i $j | sort | tail -n 3`
echo "$x"
done
done
I got what I needed with for loops in a bash script, is it possible to do this in the command line?
#!/bin/bash
for i in ABC DEF
do
for j in uvw xyz
do
x=`find . -iname $i | xargs ls | grep -i $j | sort | tail -n 3`
echo "$x"
done
done
answered Aug 8 at 23:10
kouichi
315
315
add a comment |Â
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%2f461336%2fgiven-two-patterns-search-specific-directories-and-print-last-three-file-names%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
@don_crissti is correct. I edited my question to clarify this.
â kouichi
Aug 8 at 18:40
@steeldriver, the xargs runs ls on all the folders with the name ABC in them.
â kouichi
Aug 8 at 18:41