Prev: Parsing "for" clause
Next: read multiple fields separated by : and fields separated by , in loop stored in $var
From: Wayne on 17 Mar 2010 02:56 Francis Moreau wrote: > On Mar 13, 8:48 am, Decare <dec...(a)yeah.net> wrote: >> Is there any to determine whether a string >> is a integer or not? For example, >> > > not sure which integer formats you want to support but: > > expr $s \* 0 2>&1 >/dev/null > > might do it. Many folk forget that expr has a powerful reg exp (BRE) match operator of ":": LC_ALL=C expr -- X"$ARG" : 'X[+-]\{0,1\}[[0-9]\{1,\}$' >/dev/null But the BRE syntax is ugly as is the necessary "--" and "X", so I prefer the more readable grep version: LC_ALL=C printf -- "$ARG" | grep -Exqe '(-|\+)?[0-9]+' or the single process (but a bit uglier) awk version: LC_ALL=C awk 'BEGIN { exit !(ARGV[1] ~ /^[-+]?[0-9]+$/) }' "$ARG" Since some older system use "egrep" and not "grep -E", either the expr or awk versions are likely more portable. Also in all cases, you need to ensure LC_COLLATE is set to C (or POSIX), or the range "[0-9]" may not work. On POSIX systems you could always use "[[:digit:]]" but that won't work on older, non-POSIX systems. Setting LC_COLLATE=C (or LC_ALL=C) should work fine on POSIX systems and have little effect on older systems where character class ranges may not be locale sensitive. Finally, the regular expressions used here will match "-0" and "+0", and fail on "0x00A9" and "1E3" (which are valid Integer representations in some cases). But while the OP didn't specify the purpose of the "Integer" match, that is unlikely to matter for most uses. -- Wayne
From: Chris F.A. Johnson on 17 Mar 2010 03:09 On 2010-03-17, Wayne wrote: > Francis Moreau wrote: >> On Mar 13, 8:48 am, Decare <dec...(a)yeah.net> wrote: >>> Is there any to determine whether a string >>> is a integer or not? For example, >>> >> >> not sure which integer formats you want to support but: >> >> expr $s \* 0 2>&1 >/dev/null >> >> might do it. > > Many folk forget that expr has a powerful reg exp (BRE) match > operator of ":": Most folk realize that an external command is not necessary, and a simple case statement will suffice. -- 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) ===== My code in this post, if any, assumes the POSIX locale ===== ===== and is released under the GNU General Public Licence =====
From: Janis on 17 Mar 2010 09:28 On 16 Mrz., 19:48, Dominic Fandrey <kamik...(a)bsdforen.de> wrote: > On 16/03/2010 18:34, Janis Papanagnou wrote: > > > > > > > Dominic Fandrey wrote: > >> On 15/03/2010 18:56, Stephane CHAZELAS wrote: > >>> 2010-03-15, 13:36(+01), Dominic Fandrey: > >>> [...] > >>>>> That will say that "foo<LF>1" is an integer, or that "\062" is > >>>>> an integer (with an Unix echo), the result for "12\c" is > >>>>> unspecified (unterminated line)... > >>> [...] > >>>> I cannot follow you here: > > >>>> $ echo "\062" > >>>> \062 > >>> Your echo is not Unix conformant. > > >> You're talking about POSIX? > > >> Well, I don't really care about that. POSIX doesn't even define > >> "local". How would anyone write shell scripts without "local"? > > > In ksh functions I use typeset to declare local variables. The "local" > > keyword is unknown to that shell. Is "local" available in any shell > > other than bash? Is "local" in any way "better" than "typeset", or > > vice versa? Both, local and typeset, are non-standard, certainly shell > > dependent. That makes your above claim sound silly. > > So ksh has something similar to local. Just proves that the thing > is required, at least in my book. It looks like typeset is more > portable, but ASH doesn't know it, so it's of no use to me. No, 'typeset' is not "more" portable. As 'local' it is just *not* portable. > > Recursive functions, without local or your typeset thing? > That doesn't sound nice to me. Donald Knuth, as a prominent example, implemented recusive functions based on stacks. Not elegant but quite straightforward. > > Imagine you have ~100 functions and need to make up distinct variable > names for each one? You end up with annoying prefixes and still > haven't solved the recursion problem. No prefixes. See above. But I really wonder on what problems you're using shell programs on a regular basis that you come to a conclusion that you "require" local scope in functions. Off the top of my head I cannot think of a general(!) recursive program that I'd do efficiently in shell, where most shells don't even support the most elementary data structures; either I'd have used an appropriate language for the problem, or I've made something wrong if the recursion appears as a blocker. I had used recursive approaches in (a couple) shell programs as well, but there was nothing in those solutions that - if I had no ksh functions available - I wouldn't have been able to write based on a set of (individually local scoped shell programs instead of a set of shell functions. > > The feature is needed and POSIX doesn't define it. POSIX defines a very limited subset of features, but those are portable at least. I disagree, though, that local scope is really needed. (Or to continue that line of thought; that object orientation is really needed - just to make apparent that we can continue our demands ad infinitum.) Use shell programs as your scoped entities, or subshells, as proposed elsewhere. (I'd rather like to see that POSIX defines those features that are simple and already available on modern shells, like ${ / / } and $ { : : } etc., just BTW.) Kornshell, for example, goes in the direction of enhancing the shell language to become a programming language with more data structure support; there's no end to see. I really like programming ksh with its advanced features, but you still won't have a Real Programming Language available that way. Neither fish nor fowl, and constantly changing, you can't rely on availability of features on a version that is only slightly older, and not portable to any other shell for sure. > > If you stick to POSIX you're stuck. Not seriously. Use those features that are, while non-standard, at least available with all modern shells. Janis > > Regards >
From: Jon LaBadie on 17 Mar 2010 10:18 Janis wrote: > On 16 Mrz., 19:48, Dominic Fandrey <kamik...(a)bsdforen.de> wrote: .... >> So ksh has something similar to local. Just proves that the thing >> is required, at least in my book. It looks like typeset is more >> portable, but ASH doesn't know it, so it's of no use to me. > > No, 'typeset' is not "more" portable. As 'local' it is just *not* > portable. > .... > >> The feature is needed and POSIX doesn't define it. > > POSIX defines a very limited subset of features, but those are > portable at least. > I disagree, though, that local scope is really needed. But certainly useful for writing reusable functions and keeping them as a "library". > ... Use > shell programs as your scoped entities, or subshells, as proposed > elsewhere. Yes, there are workarounds, each with their own pros&cons. > (I'd rather like to see that POSIX defines those features that are > simple and already available on modern shells, like ${ / / } and $ > { : : } etc., just BTW.) As Stephane pointed out, local is available in dash, bash, zsh, and pdksh besides the typeset of ksh88 and ksh93. Certainly that qualifies as "already available on modern shells". But maybe local scoping is not a "simple" as your prefered POSIX enhancements. Myself, I'd like to see local function scoping and your string manipulations standardized.
From: Janis on 17 Mar 2010 11:51
On 17 Mrz., 15:18, Jon LaBadie <jlaba...(a)aXcXm.org> wrote: > Janis wrote: > > On 16 Mrz., 19:48, Dominic Fandrey <kamik...(a)bsdforen.de> wrote: > ... > >> So ksh has something similar to local. Just proves that the thing > >> is required, at least in my book. It looks like typeset is more > >> portable, but ASH doesn't know it, so it's of no use to me. > > > No, 'typeset' is not "more" portable. As 'local' it is just *not* > > portable. > > ... > > >> The feature is needed and POSIX doesn't define it. > > > POSIX defines a very limited subset of features, but those are > > portable at least. > > I disagree, though, that local scope is really needed. > > But certainly useful for writing reusable functions and keeping > them as a "library". There's a lot useful, yes. Rarely "required"; which was the strong term in question. For example, ksh functions (as opposed to POSIX functions) - while not the same - have a lot structural and semantical similarities with separate shell programs (arguments, getopts, signal traps, local scope (with typeset), etc.). I can write my recursive functions (if I like so) in ksh functions or shell programs; the structural and semantical differences are comparably small and (from a plain coding POV) a "workaround" (as you call that below) not very different. I can build my libraries (and of course have done so) on the shell program abstraction level. (I've also used function libraries, and even ksh specific user-defined "builtin" functions. Rarely "required".) For the question of efficiency there could be an argument in favour of functions[*]. But considering the "recursive functions" as one apparent application where efficiency is probably most crucial, it seems - from my limited perspective - either rarely needed or typically other solutions are preferable. (Still interested in examples, for example, where you'd require time critical recursion where there are no better solutions.) WRT libraries of functions there are also different features in the various shells supported; non- portable, usually. [*] Similar to the (arguable) introduction of threads in addition to processes. > > > ... Use > > > shell programs as your scoped entities, or subshells, as proposed > > elsewhere. > > Yes, there are workarounds, each with their own pros&cons. > > > (I'd rather like to see that POSIX defines those features that are > > simple and already available on modern shells, like ${ / / } and $ > > { : : } etc., just BTW.) > > As Stephane pointed out, local is available in dash, bash, zsh, and > pdksh besides the typeset of ksh88 and ksh93. Certainly that qualifies > as "already available on modern shells". Ksh maintains a strong place in the set of the "modern shells"; if some feature is not supported by any of ksh, bash, or zsh, that feature should IMO be used reluctantly. In c.u.s I try to avoid 'typeset' (and 'local'), but I regularily suggest, for example, despite not being POSIX, the string manipulation functions. Because the latter is available in all the prominent shells that you find on not too old systems. > But maybe local scoping is > not a "simple" as your prefered POSIX enhancements. Myself, I'd like > to see local function scoping and your string manipulations standardized. I would like to see a consistent standard on a feature level that is sufficiently high; POSIX is not. And I would like to see a clearly visible and converging development path with all the shells so that any standard has a chance to define a large enough subset; which is also not the case. The Kornshell typeset, BTW, has more purposes than being just a local variable declaration - so hardly to believe that they agree on that. Janis |