If I have a file.txt in a directory, I can echo "hello" as follows:
if [ -a file.txt ];
then
echo "hello";
fi
But how can I use a wildcard in this situation, such as *.txt and echo if
there is one or more matches? For example:
if [ -a *.txt ];
then
echo "hello";
fi
Wtih the above, although if there's no match there's no error or echo,
which is correct, but if there is one match the error "[: file.txt: binary
operator expected" occurs, or if there are more matches the error "[: too
many arguments" occurs. How can this type of wildcard check done in bash?
Many thanks,
Tuxedo
|
|
0
|
|
|
|
Reply
|
Tuxedo
|
2/24/2011 11:24:23 PM |
|
Tuxedo <tuxedo@mailinator.com> writes:
> If I have a file.txt in a directory, I can echo "hello" as follows:
>
> if [ -a file.txt ];
> then
> echo "hello";
> fi
>
> But how can I use a wildcard in this situation, such as *.txt and echo if
> there is one or more matches? For example:
>
> if [ -a *.txt ];
> then
> echo "hello";
> fi
>
> Wtih the above, although if there's no match there's no error or echo,
> which is correct, but if there is one match the error "[: file.txt: binary
> operator expected" occurs, or if there are more matches the error "[: too
> many arguments" occurs. How can this type of wildcard check done in
> bash?
I think you want to test if a glob does or does not match some files.
First off, forget -a: it is useful only between tests. You could use -n
to test is a single string is not empty. To do that you need to get the
result of the glob quoted. There are lots of ways to do this but these
spring to mind:
FILELIST=*.txt
if [ -n "$FILELIST" ]
or
if [ -n "$(printf %s *.txt)" ]
You can also use a bash array:
FILELIST=(*.txt)
if [ ${#FILELIST[*]} -gt 0 ]
If the number of matches might be very large you are probably better off
avoiding "*.txt" altogether. 'find' could be used but that's a little
more complex and may be overkill though it does free you from
any problems to do with shell glob options:
if [ -n "$(find . -maxdepth 1 -name '*.c' -print -quit)" ]
--
Ben.
|
|
0
|
|
|
|
Reply
|
Ben
|
2/25/2011 12:45:09 AM
|
|
On 2011-02-24, Tuxedo wrote:
> If I have a file.txt in a directory, I can echo "hello" as follows:
>
> if [ -a file.txt ];
> then
> echo "hello";
> fi
>
> But how can I use a wildcard in this situation, such as *.txt and echo if
> there is one or more matches? For example:
>
> if [ -a *.txt ];
> then
> echo "hello";
> fi
>
> Wtih the above, although if there's no match there's no error or echo,
> which is correct, but if there is one match the error "[: file.txt: binary
> operator expected" occurs, or if there are more matches the error "[: too
> many arguments" occurs. How can this type of wildcard check done in bash?
is_file ()
{
for f in "$@"
do
[ -f "$f" ] && return
done
return 1
}
if is_file *.txt
then
echo Hello
fi
--
Chris F.A. Johnson, author <http://shell.cfajohnson.com/>
===================================================================
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
|
|
0
|
|
|
|
Reply
|
Chris
|
2/25/2011 1:31:50 AM
|
|
Chris F.A. Johnson wrote:
[...]
> is_file ()
> {
> for f in "$@"
> do
> [ -f "$f" ] && return
> done
> return 1
> }
>
> if is_file *.txt
> then
> echo Hello
> fi
>
Thanks for posting this as well as to Ben for posting the ideas in the
prior post. All have been tested and work fine!
Tuxedo
|
|
0
|
|
|
|
Reply
|
Tuxedo
|
2/25/2011 5:16:21 PM
|
|
On 25.02.2011 00:24, Tuxedo wrote:
> If I have a file.txt in a directory, I can echo "hello" as follows:
>
> if [ -a file.txt ];
> then
> echo "hello";
> fi
>
> But how can I use a wildcard in this situation, such as *.txt and echo if
> there is one or more matches? For example:
>
> if [ -a *.txt ];
> then
> echo "hello";
> fi
>
> Wtih the above, although if there's no match there's no error or echo,
> which is correct, but if there is one match the error "[: file.txt: binary
> operator expected" occurs, or if there are more matches the error "[: too
> many arguments" occurs. How can this type of wildcard check done in bash?
Other options...
: *.txt
[ -e "$_" ] && echo Hello
set -- *.txt
[ -e "$1" ] && echo Hello
Janis
>
> Many thanks,
> Tuxedo
>
|
|
0
|
|
|
|
Reply
|
Janis
|
2/25/2011 8:50:14 PM
|
|
2011-02-25, 21:50(+01), Janis Papanagnou:
[...]
> set -- *.txt
> [ -e "$1" ] && echo Hello
[...]
$ ln -s /xxx a.txt
$ touch b.txt
$ set -- *.txt
$ [ -e "$1" ] || echo no
no
You may want:
set -- [*].txt *.txt
if [ "$1$2" != "[*].txt*.txt" ]; then
shift
echo There are txt files:
printf ' %s\n' "$@"
else
echo >&2 "There doesn't appear to be any txt file here"
fi
--
Stephane
|
|
0
|
|
|
|
Reply
|
Stephane
|
2/25/2011 9:07:19 PM
|
|
On 25.02.2011 00:24, Tuxedo wrote:
> If I have a file.txt in a directory, I can echo "hello" as follows:
>
> if [ -a file.txt ];
> then
> echo "hello";
> fi
>
> But how can I use a wildcard in this situation, such as *.txt and echo if
> there is one or more matches? For example:
>
> if [ -a *.txt ];
> then
> echo "hello";
> fi
>
> Wtih the above, although if there's no match there's no error or echo,
> which is correct, but if there is one match the error "[: file.txt: binary
> operator expected" occurs, or if there are more matches the error "[: too
> many arguments" occurs. How can this type of wildcard check done in bash?
in bash you can set the shell option `failglob', so bash will return an
error if the glob does not match anything:
shopt -s failglob
(for x in *.txt; do echo hello; break; done 2>/dev/null) || echo no
files match
Best regards
Mart
|
|
0
|
|
|
|
Reply
|
Mart
|
2/26/2011 10:03:35 AM
|
|
On Feb 26, 2:07=A0am, Stephane CHAZELAS <stephane_chaze...@yahoo.fr>
wrote:
> 2011-02-25, 21:50(+01), Janis Papanagnou:
> [...]> set -- *.txt
> > [ -e "$1" ] && echo Hello
>
> [...]
>
> $ ln -s /xxx a.txt
> $ touch b.txt
> $ set -- *.txt
> $ [ -e "$1" ] || echo no
> no
>
> You may want:
>
> set -- [*].txt *.txt
>
> if [ "$1$2" !=3D "[*].txt*.txt" ]; then
> =A0 shift
> =A0 echo There are txt files:
> =A0 printf ' =A0%s\n' "$@"
> else
> =A0 echo >&2 "There doesn't appear to be any txt file here"
> fi
>
> --
> Stephane
Stephane,
Can you please explain how the above code works?
-- Rakesh
|
|
0
|
|
|
|
Reply
|
Rakesh
|
2/28/2011 5:02:20 PM
|
|
2011-02-28, 09:02(-08), Rakesh Sharma:
[...]
>> set -- [*].txt *.txt
>>
>> if [ "$1$2" != "[*].txt*.txt" ]; then
>> shift
>> echo There are txt files:
>> printf ' %s\n' "$@"
>> else
>> echo >&2 "There doesn't appear to be any txt file here"
>> fi
[...]
> Stephane,
> Can you please explain how the above code works?
[...]
That trick was introduced here by Laura Fairhead some time ago.
In
set -- *.txt
*.txt would expand to "*.txt" if there's no txt file (well, if
no non-hidden txt file can be found in the current directory),
so you may think of doing:
if [ "$1" = "*.txt" ]; then echo "there's no txt file"
The problem is that *.txt also expands to "*.txt" if there's one
txt file called "*.txt". To differentiate that case, we use
another pattern: [*].txt that also matches the "*.txt" file.
If there's no txt file, "[*].txt *.txt" will expand to "[*].txt
*.txt", if there's a file called "*.txt", it will expand
to "*.txt whatever", if there's no file called "*.txt", but a
whatever.txt file it will expand to "[*].txt whatever.txt",
"whatever" not being "*".
--
Stephane
|
|
0
|
|
|
|
Reply
|
Stephane
|
2/28/2011 8:44:55 PM
|
|
|
8 Replies
514 Views
(page loaded in 0.12 seconds)
Similiar Articles: Wildcard match? - comp.unix.shellIf I have a file.txt in a directory, I can echo "hello" as follows: if [ -a file.txt ]; then echo "hello"; fi But how can I use a wildcard in... wildcard matching algorithm - comp.lang.rexxDoes anybody have an efficient, conventional rexx implementation of a wildcard matching algorithm? Hopefully with positionals, i.e. "?" as well as "*"... how to match "$" in expect, instead of using it as a wildcard ...Hi I am writing a expect script about the automatic login session, pretty basic. :) but i found that expect take "$" as a wildcard, and don't ... pattern match and dw in vim - comp.unix.adminwildcard matching algorithm - comp.lang.rexx pattern match and dw in vim - comp.unix.admin Wildcard match? - comp.unix.shell Remove prefix from ... algorithm - comp.lang ... Remove prefix from filename? - comp.graphics.apps.paint-shop-pro ...wildcard matching algorithm - comp.lang.rexx Remove prefix from filename? - comp.graphics.apps.paint-shop-pro ... wildcard matching algorithm - comp.lang.rexx Remove ... switch/case with wildcards? - comp.soft-sys.matlabI know switch/case can use multiple case_expr values, e.g., {'this','that'} and that if any of them match, that case statement will execute. Is there... Update Statement - Replace, Wildcard, and partial update? - comp ...The function looks for an exact match of 5 number characters in a row. ... Update Statement - Replace, Wildcard, and partial update? - comp ... Hi, I am trying to ... a*star algorithm in 3D - comp.soft-sys.matlabwildcard matching algorithm - comp.lang.rexx... have an efficient, conventional rexx implementation of a wildcard matching algorithm? ... Here is my latest code ... Bash Test for Partial Match of String - comp.unix.shellUpdate Statement - Replace, Wildcard, and partial update? - comp ... Bash Test for Partial Match of String - comp.unix.shell Update Statement - Replace, Wildcard, and ... REXX Listcat example in TSO 3.4 option? - comp.lang.rexx ...wildcard matching algorithm - comp.lang.rexx REXX Listcat example in TSO 3.4 option? - comp.lang.rexx ... In TSO 3.4: DSLIST - Data Sets Matching TSO.VSAM.CLUSTER Row 1 of ... Wildcard matching algorithms - VirgilioWildcard matching algorithms comparisone and source code ... Introduction The code described below is focused on the design of an algorithm to compare a pattern ... Wildcard Matching - The GNU C LibraryThe GNU C Library ... 10.1 Wildcard Matching. This section describes how to match a wildcard pattern against a particular string. 7/20/2012 9:45:20 AM
|