Question - List files in a directory using -grep
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
The question wants me to list all the files stored in /usr/bin
which the file names only contain lowercase English letters and contain the word 'file'.
For example, nsrfile
and file
should be in the output
Here's my code to achieve this
ls /usr/bin | grep '<[a-z]*file[a-z]*>'
and here's some part of the result I get.
file
nsrfile
grub2-file
systemd-tmpfiles
however, the question says that the file name should only contain lowercase English letters but not the slash -
and grub2-file
even contains a number
how should I change my commands?
grep ls
add a comment |Â
up vote
0
down vote
favorite
The question wants me to list all the files stored in /usr/bin
which the file names only contain lowercase English letters and contain the word 'file'.
For example, nsrfile
and file
should be in the output
Here's my code to achieve this
ls /usr/bin | grep '<[a-z]*file[a-z]*>'
and here's some part of the result I get.
file
nsrfile
grub2-file
systemd-tmpfiles
however, the question says that the file name should only contain lowercase English letters but not the slash -
and grub2-file
even contains a number
how should I change my commands?
grep ls
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
The question wants me to list all the files stored in /usr/bin
which the file names only contain lowercase English letters and contain the word 'file'.
For example, nsrfile
and file
should be in the output
Here's my code to achieve this
ls /usr/bin | grep '<[a-z]*file[a-z]*>'
and here's some part of the result I get.
file
nsrfile
grub2-file
systemd-tmpfiles
however, the question says that the file name should only contain lowercase English letters but not the slash -
and grub2-file
even contains a number
how should I change my commands?
grep ls
The question wants me to list all the files stored in /usr/bin
which the file names only contain lowercase English letters and contain the word 'file'.
For example, nsrfile
and file
should be in the output
Here's my code to achieve this
ls /usr/bin | grep '<[a-z]*file[a-z]*>'
and here's some part of the result I get.
file
nsrfile
grub2-file
systemd-tmpfiles
however, the question says that the file name should only contain lowercase English letters but not the slash -
and grub2-file
even contains a number
how should I change my commands?
grep ls
edited Jan 31 at 22:34
Isaac
6,6371734
6,6371734
asked Jan 31 at 18:13
Ulysses
496
496
add a comment |Â
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
0
down vote
accepted
Expectation and warning
Your assignment may expect you to grep
the output of ls
, perhaps something like this:
cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file
Where you ask ls
for the filenames, then have grep
filter ones that start (^
) and end ($
) with only lower-case letters -- zero or more of them (*
); you then ask xargs
to grep each incoming filename for the string "file".
This runs into immediate trouble as soon as any filenames (unlikely as these are to be in /usr/bin) contain a newline. (Files with spaces in them Some File Name
will be excluded by the grep.) For a contrived example to show the point:
cd ~/tmp/usr/bin
touch a$'n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory
In the above example, ls
wrote the following contents to the pipe for grep:
a
b
Grep rightfully passed both of those "filenames" down the pipe to xargs, which then thought it had two filenames to grep against, and so it ran:
grep file a b
... which then complained about the missing files.
Suggestion
While it's not expectedd, I would suggest the following safer option, assuming a bash shell:
shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)
This turns on bash's extended globbing functionality. You then ask grep
to list the filenames (-l
) that contain the string "file" among the files in /usr/bin that do not (!
) match the pattern: "anything (*
) followed by any single ([ ... ]
) non (^
) -lower-case letter (a-z
), followed by anything (*
). In other words, only files that contain only lower-case letters in their name.
Thanks so much for those details.xargs
would be the best thing I've learnt today
â Ulysses
Jan 31 at 20:02
add a comment |Â
up vote
0
down vote
What I would do :
printf '%sn' /usr/bin/* |
grep '<[a-z]*file[a-z]*>' | grep -Ev '[0-9]|-'
Explanation :
grep -v
is a reverse grep. There are two patterns: [0-9]
and -
for yourgrep -Ev
part. can I use'[^a-z]'
because there might be other symbols
â Ulysses
Jan 31 at 18:24
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
add a comment |Â
up vote
0
down vote
You were close to the goal, just change the "word-boundary" (<>) limits to the start of line and end of line (^$) limits and all will be fine:
$ ls /usr/bin | grep '^[a-z]*file[a-z]*$'
file
nsrfile
That is: starting from the start of each line find lines that contain any amount of lowercase letters (a-z) zero or more times followed by the word file and lowercase letters again until the end of the line.
Note that the above command will not work correctly for filenames with newlines.
add a comment |Â
up vote
0
down vote
Two solutions:
A shell loop:
for name in /usr/bin/*file*; do
case "$name##*/" in
*[!a-z]*) ;;
*) printf '%sn' "$name"
esac
done
This first generates a list of pathnames under /usr/bin
whose basename matches *file*
and then tests whether those basenames also contains characters that are not lowercase letters. If no non-lowercase letters are found, the pathname is printed.
This would potentially also find names of directories that fulfil the criteria. If that is not wanted, just do
[ ! -f "$name" ] && continue
before the case
statement to skip every name that is not a regular file.
Using GNU find
:
find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'
This also does a two stage filtering. First on the basename which must match *file*
, and then on the end of the pathname (-regex
matches against the complete pathname) to make sure there's only lowercase letters there.
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
Expectation and warning
Your assignment may expect you to grep
the output of ls
, perhaps something like this:
cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file
Where you ask ls
for the filenames, then have grep
filter ones that start (^
) and end ($
) with only lower-case letters -- zero or more of them (*
); you then ask xargs
to grep each incoming filename for the string "file".
This runs into immediate trouble as soon as any filenames (unlikely as these are to be in /usr/bin) contain a newline. (Files with spaces in them Some File Name
will be excluded by the grep.) For a contrived example to show the point:
cd ~/tmp/usr/bin
touch a$'n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory
In the above example, ls
wrote the following contents to the pipe for grep:
a
b
Grep rightfully passed both of those "filenames" down the pipe to xargs, which then thought it had two filenames to grep against, and so it ran:
grep file a b
... which then complained about the missing files.
Suggestion
While it's not expectedd, I would suggest the following safer option, assuming a bash shell:
shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)
This turns on bash's extended globbing functionality. You then ask grep
to list the filenames (-l
) that contain the string "file" among the files in /usr/bin that do not (!
) match the pattern: "anything (*
) followed by any single ([ ... ]
) non (^
) -lower-case letter (a-z
), followed by anything (*
). In other words, only files that contain only lower-case letters in their name.
Thanks so much for those details.xargs
would be the best thing I've learnt today
â Ulysses
Jan 31 at 20:02
add a comment |Â
up vote
0
down vote
accepted
Expectation and warning
Your assignment may expect you to grep
the output of ls
, perhaps something like this:
cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file
Where you ask ls
for the filenames, then have grep
filter ones that start (^
) and end ($
) with only lower-case letters -- zero or more of them (*
); you then ask xargs
to grep each incoming filename for the string "file".
This runs into immediate trouble as soon as any filenames (unlikely as these are to be in /usr/bin) contain a newline. (Files with spaces in them Some File Name
will be excluded by the grep.) For a contrived example to show the point:
cd ~/tmp/usr/bin
touch a$'n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory
In the above example, ls
wrote the following contents to the pipe for grep:
a
b
Grep rightfully passed both of those "filenames" down the pipe to xargs, which then thought it had two filenames to grep against, and so it ran:
grep file a b
... which then complained about the missing files.
Suggestion
While it's not expectedd, I would suggest the following safer option, assuming a bash shell:
shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)
This turns on bash's extended globbing functionality. You then ask grep
to list the filenames (-l
) that contain the string "file" among the files in /usr/bin that do not (!
) match the pattern: "anything (*
) followed by any single ([ ... ]
) non (^
) -lower-case letter (a-z
), followed by anything (*
). In other words, only files that contain only lower-case letters in their name.
Thanks so much for those details.xargs
would be the best thing I've learnt today
â Ulysses
Jan 31 at 20:02
add a comment |Â
up vote
0
down vote
accepted
up vote
0
down vote
accepted
Expectation and warning
Your assignment may expect you to grep
the output of ls
, perhaps something like this:
cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file
Where you ask ls
for the filenames, then have grep
filter ones that start (^
) and end ($
) with only lower-case letters -- zero or more of them (*
); you then ask xargs
to grep each incoming filename for the string "file".
This runs into immediate trouble as soon as any filenames (unlikely as these are to be in /usr/bin) contain a newline. (Files with spaces in them Some File Name
will be excluded by the grep.) For a contrived example to show the point:
cd ~/tmp/usr/bin
touch a$'n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory
In the above example, ls
wrote the following contents to the pipe for grep:
a
b
Grep rightfully passed both of those "filenames" down the pipe to xargs, which then thought it had two filenames to grep against, and so it ran:
grep file a b
... which then complained about the missing files.
Suggestion
While it's not expectedd, I would suggest the following safer option, assuming a bash shell:
shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)
This turns on bash's extended globbing functionality. You then ask grep
to list the filenames (-l
) that contain the string "file" among the files in /usr/bin that do not (!
) match the pattern: "anything (*
) followed by any single ([ ... ]
) non (^
) -lower-case letter (a-z
), followed by anything (*
). In other words, only files that contain only lower-case letters in their name.
Expectation and warning
Your assignment may expect you to grep
the output of ls
, perhaps something like this:
cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file
Where you ask ls
for the filenames, then have grep
filter ones that start (^
) and end ($
) with only lower-case letters -- zero or more of them (*
); you then ask xargs
to grep each incoming filename for the string "file".
This runs into immediate trouble as soon as any filenames (unlikely as these are to be in /usr/bin) contain a newline. (Files with spaces in them Some File Name
will be excluded by the grep.) For a contrived example to show the point:
cd ~/tmp/usr/bin
touch a$'n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory
In the above example, ls
wrote the following contents to the pipe for grep:
a
b
Grep rightfully passed both of those "filenames" down the pipe to xargs, which then thought it had two filenames to grep against, and so it ran:
grep file a b
... which then complained about the missing files.
Suggestion
While it's not expectedd, I would suggest the following safer option, assuming a bash shell:
shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)
This turns on bash's extended globbing functionality. You then ask grep
to list the filenames (-l
) that contain the string "file" among the files in /usr/bin that do not (!
) match the pattern: "anything (*
) followed by any single ([ ... ]
) non (^
) -lower-case letter (a-z
), followed by anything (*
). In other words, only files that contain only lower-case letters in their name.
answered Jan 31 at 18:45
Jeff Schaller
31.4k846105
31.4k846105
Thanks so much for those details.xargs
would be the best thing I've learnt today
â Ulysses
Jan 31 at 20:02
add a comment |Â
Thanks so much for those details.xargs
would be the best thing I've learnt today
â Ulysses
Jan 31 at 20:02
Thanks so much for those details.
xargs
would be the best thing I've learnt todayâ Ulysses
Jan 31 at 20:02
Thanks so much for those details.
xargs
would be the best thing I've learnt todayâ Ulysses
Jan 31 at 20:02
add a comment |Â
up vote
0
down vote
What I would do :
printf '%sn' /usr/bin/* |
grep '<[a-z]*file[a-z]*>' | grep -Ev '[0-9]|-'
Explanation :
grep -v
is a reverse grep. There are two patterns: [0-9]
and -
for yourgrep -Ev
part. can I use'[^a-z]'
because there might be other symbols
â Ulysses
Jan 31 at 18:24
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
add a comment |Â
up vote
0
down vote
What I would do :
printf '%sn' /usr/bin/* |
grep '<[a-z]*file[a-z]*>' | grep -Ev '[0-9]|-'
Explanation :
grep -v
is a reverse grep. There are two patterns: [0-9]
and -
for yourgrep -Ev
part. can I use'[^a-z]'
because there might be other symbols
â Ulysses
Jan 31 at 18:24
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
add a comment |Â
up vote
0
down vote
up vote
0
down vote
What I would do :
printf '%sn' /usr/bin/* |
grep '<[a-z]*file[a-z]*>' | grep -Ev '[0-9]|-'
Explanation :
grep -v
is a reverse grep. There are two patterns: [0-9]
and -
What I would do :
printf '%sn' /usr/bin/* |
grep '<[a-z]*file[a-z]*>' | grep -Ev '[0-9]|-'
Explanation :
grep -v
is a reverse grep. There are two patterns: [0-9]
and -
answered Jan 31 at 18:19
Gilles Quenot
15.3k13448
15.3k13448
for yourgrep -Ev
part. can I use'[^a-z]'
because there might be other symbols
â Ulysses
Jan 31 at 18:24
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
add a comment |Â
for yourgrep -Ev
part. can I use'[^a-z]'
because there might be other symbols
â Ulysses
Jan 31 at 18:24
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
for your
grep -Ev
part. can I use '[^a-z]'
because there might be other symbolsâ Ulysses
Jan 31 at 18:24
for your
grep -Ev
part. can I use '[^a-z]'
because there might be other symbolsâ Ulysses
Jan 31 at 18:24
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
| grep -Ev '[^a-z]'
â Ulysses
Jan 31 at 18:25
add a comment |Â
up vote
0
down vote
You were close to the goal, just change the "word-boundary" (<>) limits to the start of line and end of line (^$) limits and all will be fine:
$ ls /usr/bin | grep '^[a-z]*file[a-z]*$'
file
nsrfile
That is: starting from the start of each line find lines that contain any amount of lowercase letters (a-z) zero or more times followed by the word file and lowercase letters again until the end of the line.
Note that the above command will not work correctly for filenames with newlines.
add a comment |Â
up vote
0
down vote
You were close to the goal, just change the "word-boundary" (<>) limits to the start of line and end of line (^$) limits and all will be fine:
$ ls /usr/bin | grep '^[a-z]*file[a-z]*$'
file
nsrfile
That is: starting from the start of each line find lines that contain any amount of lowercase letters (a-z) zero or more times followed by the word file and lowercase letters again until the end of the line.
Note that the above command will not work correctly for filenames with newlines.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
You were close to the goal, just change the "word-boundary" (<>) limits to the start of line and end of line (^$) limits and all will be fine:
$ ls /usr/bin | grep '^[a-z]*file[a-z]*$'
file
nsrfile
That is: starting from the start of each line find lines that contain any amount of lowercase letters (a-z) zero or more times followed by the word file and lowercase letters again until the end of the line.
Note that the above command will not work correctly for filenames with newlines.
You were close to the goal, just change the "word-boundary" (<>) limits to the start of line and end of line (^$) limits and all will be fine:
$ ls /usr/bin | grep '^[a-z]*file[a-z]*$'
file
nsrfile
That is: starting from the start of each line find lines that contain any amount of lowercase letters (a-z) zero or more times followed by the word file and lowercase letters again until the end of the line.
Note that the above command will not work correctly for filenames with newlines.
answered Jan 31 at 22:47
Isaac
6,6371734
6,6371734
add a comment |Â
add a comment |Â
up vote
0
down vote
Two solutions:
A shell loop:
for name in /usr/bin/*file*; do
case "$name##*/" in
*[!a-z]*) ;;
*) printf '%sn' "$name"
esac
done
This first generates a list of pathnames under /usr/bin
whose basename matches *file*
and then tests whether those basenames also contains characters that are not lowercase letters. If no non-lowercase letters are found, the pathname is printed.
This would potentially also find names of directories that fulfil the criteria. If that is not wanted, just do
[ ! -f "$name" ] && continue
before the case
statement to skip every name that is not a regular file.
Using GNU find
:
find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'
This also does a two stage filtering. First on the basename which must match *file*
, and then on the end of the pathname (-regex
matches against the complete pathname) to make sure there's only lowercase letters there.
add a comment |Â
up vote
0
down vote
Two solutions:
A shell loop:
for name in /usr/bin/*file*; do
case "$name##*/" in
*[!a-z]*) ;;
*) printf '%sn' "$name"
esac
done
This first generates a list of pathnames under /usr/bin
whose basename matches *file*
and then tests whether those basenames also contains characters that are not lowercase letters. If no non-lowercase letters are found, the pathname is printed.
This would potentially also find names of directories that fulfil the criteria. If that is not wanted, just do
[ ! -f "$name" ] && continue
before the case
statement to skip every name that is not a regular file.
Using GNU find
:
find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'
This also does a two stage filtering. First on the basename which must match *file*
, and then on the end of the pathname (-regex
matches against the complete pathname) to make sure there's only lowercase letters there.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Two solutions:
A shell loop:
for name in /usr/bin/*file*; do
case "$name##*/" in
*[!a-z]*) ;;
*) printf '%sn' "$name"
esac
done
This first generates a list of pathnames under /usr/bin
whose basename matches *file*
and then tests whether those basenames also contains characters that are not lowercase letters. If no non-lowercase letters are found, the pathname is printed.
This would potentially also find names of directories that fulfil the criteria. If that is not wanted, just do
[ ! -f "$name" ] && continue
before the case
statement to skip every name that is not a regular file.
Using GNU find
:
find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'
This also does a two stage filtering. First on the basename which must match *file*
, and then on the end of the pathname (-regex
matches against the complete pathname) to make sure there's only lowercase letters there.
Two solutions:
A shell loop:
for name in /usr/bin/*file*; do
case "$name##*/" in
*[!a-z]*) ;;
*) printf '%sn' "$name"
esac
done
This first generates a list of pathnames under /usr/bin
whose basename matches *file*
and then tests whether those basenames also contains characters that are not lowercase letters. If no non-lowercase letters are found, the pathname is printed.
This would potentially also find names of directories that fulfil the criteria. If that is not wanted, just do
[ ! -f "$name" ] && continue
before the case
statement to skip every name that is not a regular file.
Using GNU find
:
find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'
This also does a two stage filtering. First on the basename which must match *file*
, and then on the end of the pathname (-regex
matches against the complete pathname) to make sure there's only lowercase letters there.
answered May 20 at 15:45
Kusalananda
103k13202318
103k13202318
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%2f421032%2fquestion-list-files-in-a-directory-using-grep%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