The code looks something like this:
if [ -f msg.* ]
then tar -czf msgs.tar.gz msg.*
fi
I was getting an error like this: "[: too many arguments".
I think the asterisk in the test was being expanded to include all files
beginning with msg, and the test program only wants one argument.
So how do I test to see if ANY file with that prefix exists, without
passing the test program all of those files that do exist?
Thanks for your patience, I'm an amateur!
ls msg.*
>
> Thanks for your patience, I'm an amateur!
--
William Park, Open Geometry Consulting, <openge...@yahoo.ca>
Linux solution for data management and processing.
set -- msg.*
if [ -f "$1" ] ...
John
--
John DuBois spc...@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
That probably solves OP's problem, but note that the first
msg.xxx may exist but not be a regular file (or a symlink to a
regular file). Strictly speaking, you would have to check for
all positional parameters, or use things like "ls -ld msg.* 2>
/dev/null | grep '^-' > /dev/null" (provided that file names
don't contain newlines).
With zsh:
[ -f msg.*(-.[1]^N) ]
--
Stéphane
>I have an sh script wherein I want to test to see if a directory has
>text files named "msg.xxxx," where xxxx is a series of random letters.
>
>The code looks something like this:
>
> if [ -f msg.* ]
> then tar -czf msgs.tar.gz msg.*
> fi
>
>I was getting an error like this: "[: too many arguments".
>
>I think the asterisk in the test was being expanded to include all files
>beginning with msg, and the test program only wants one argument.
Yeah.
>
>So how do I test to see if ANY file with that prefix exists, without
>passing the test program all of those files that do exist?
>
>Thanks for your patience, I'm an amateur!
You can take only the first word from the expansion of
'msg.*' and test that;
if ( set msg.*; [ -f "$1" ] )
then
tar -czf msgs.tar.gz msg.*
fi
[ the 'set' is executed in a sub-shell to avoid messing around
with the main script positional parameters ]
That will execute the 'tar' if there is at least one file
msg.* and the first file in the expanded list is a regular file.
Since testing one file for being regular might be regarded
as good as nothing in this case, due to the fact that any
of the other files could be non-regular files (eg: directory,
device, ...) you may think that you could just test that
the first parameter in the expansion was not the string
'msg.*' but it is possible that you can have a file called
this name in UNIX so that test wouldn't be good enough.
You could, however, get rid of the use of the sub-shell
(probably the lost efficiency is nothing compared to the
'tar' command but this is just another way );
for file in msg.*
do
[ -f "$file" ] && tar -czf msgs.tar.gz msg.*
break
done
This time 'for' is used in order to get the first word
from the expansion 'msg.*'. That word is checked and
it will 'tar' if it is a file, whether or not it is
it always exits because of the 'break' after only the
one loop.
byefornow
laura
--
alt.fan.madonna |news, interviews, discussion, writings
|chat, exchange merchandise, meet fans....
|Get into the groove baby you've got to... check us out!
for i in `ls msg.*`
do
tar -czf msgs.tar.gz $i
done
"William Park" <openge...@yahoo.ca> wrote in message
news:b3um5n$1pns9v$1...@ID-99293.news.dfncis.de...
> Octually, just run a for loop
>
> for i in `ls msg.*`
Why ls? Isn't that equivalent with
for i in msg.*
??
--
Tapani Tarvainen
One would wish so, but if no files matching the msg.*
pattern actually exist, then the for loop will assign
the string "msg.*" to $x and execute the loop once.
Ie, this loop,
for x in *.msg ; do
echo $x
done
is not the same as this loop,
for x in `ls *.msg 2> /dev/null` ; do
echo $x
done
in the case where no files match the pattern. The first
example prints this output,
msg.*
whereas the second prints nothing.
--
David Thompson
dat...@yahoo.com
Er, (*blush*) I've mixed that up, above should be *.msg,
but the OP's example used msg.*, sorry about that, my
fingers weren't paying attention.
--
David Thompson
dat...@yahoo.com
ls *.msg > /dev/null 2>&1 && tar ......
(choose redirection appropriate to your shell. Above suits ksh)
The problem with the `ls` construct is that if file name contain
any IFS character, the list will be broken.
One way to avoid the problem without using ls is:
zsh: setopt nullglob (or add "(N)" to the pattern)
bash: shopt -s nullglob
other shells:
set -- *.msg *[.]msg
case $* in
"*.msg *[.]msg") # no match found
;;
*)
for x in *.msg; do ...; done;;
esac
--
Stéphane
Like the idea :) I was wondering if you could do this
this morning, seems I don't have to wonder anymore...
Anyway, how about a simplification;
set -- *[.]msg
case $1 in
"*[.]msg") # no match found
;;
*) for x ; do ...; done;;
esac
Maybe it makes no difference, but could save a few directory
re-reads
>
>--
>Stéphane
bestwishes
Right you are. In that particular case, it's enough. I was
actually reusing a construct I had imagined few hours earlier to
test wether a directory is empty or not (or contains only dot
files or is not readable...)
set x * ?*
case "$# $1 $2" in
"3 * ?*") # dir empty
;;
*) # not empty
;;
esac
--
Stéphane
> "Tapani Tarvainen" wrote
>
>>"Alan Perry" <alan...@covad.net> writes:
>>
>>
>>>Octually, just run a for loop
>>>
>>>for i in `ls msg.*`
>>>
>>Why ls? Isn't that equivalent with
>>
>>for i in msg.*
>>
>
> One would wish so, but if no files matching the msg.*
> pattern actually exist, then the for loop will assign
> the string "msg.*" to $x and execute the loop once.
>
> Ie, this loop,
>
> for x in *.msg ; do
> echo $x
> done
>
> is not the same as this loop,
>
> for x in `ls *.msg 2> /dev/null` ; do
> echo $x
> done
Which is why the idiomatic usage is
for x in *.msg; do
[ -f "$x" ] || continue
# your code here
done
--
<a href="mailto:<kevin.rodgers@ihs.com>">Kevin Rodgers</a>
>On Tue, 04 Mar 2003 01:01:04 GMT, laura fairhead <LoveMrs...@madonnaweb.com> wrote:
How about this to check for any files except '.' and '..';
set x * [*] .[!.]* '.[!.]'[*] .[.]?*
case $* in
"x * [*] .[!.]* .[!.][*] .[.]?*") # no files
;;
*) # files found
;;
esac
This is ny attempt at a proof (not satsified with it yet somehow);
There are 5 SPACE, this means that no SPACE could be added
by a filename (and they can't be taken away) so therefore
each filename is deliminated by a SPACE character, then
working right to left through the matching result string;
1 2 3 4 5
set x * [*] .[!.]* '.[!.]'[*] .[.]?*
RESULT STRING
v
.[.]?* (5) This implies that no file matching ..?* exists
.[!.][*] (4) This implies that no file called ".[!.]*" exists
.[!.]* (3) This implies no file matching .[!.]* exists
(because of the previous, no file ".[!.]*" exist)
So now there are no .* files except '.' and '..'
[*] (2) This implies no file called "*" exists
* (1) This implies (because not file "*") that no file matching *
exists
Hence, implies no files exist except '.' and '..'
This is one-way because result => no files
The other way around (no files => result) is just trivial
#
Not yet completely happy with this (it's the wrong time in the
morning, haha) but it seems okay generally,...
For a challenge get it down to 4 filename patterns only !
So then we have a test for 'any non-hidden files' in the current
directory and also 'any files' in the current. If all this could be
made to work on an arbitrary directory I would say it could even
go into the FAQ.
:-)
>
>--
>Stéphane
buenosdias
Bright, as usual! The [*] idea is far better as my ?* that
duplicates the file list.
[...]
> For a challenge get it down to 4 filename patterns only !
Easy ;)
IFS=" " # to ensure "$*" is space separated
set x * [*] .* .[*]
case $* in
"x * [*] . .. .[*]"|\
"x * [*] . .[*]"|\
"x * [*] .. .[*]"|\
"x * [*] .* .[*]") ...
*) ...
esac
But I much prefer yours ;)
--
Stéphane