|
Home > Archive > Unix Programming > September 2007 > Beginner Question (related to homework)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Beginner Question (related to homework)
|
|
| prelim_questions@yahoo.com 2007-09-24, 7:23 pm |
| I need to perform a complicated (for me) operation at the command line
using a series of pipes, but not using grep, sed, or awk.
At one point I may have a list as follows:
1.2
3.45
6.7
a
bc
Is there an easy way to count only the numeric lines? I do not know
in advance how many lines are numbers and how many are strictly
alphabetic. There are no mixed lines.
Thanks in advance.
| |
| prelim_questions@yahoo.com 2007-09-24, 7:23 pm |
| Ok. I think for my purpose I can use: >> ... | sort | xargs
-E firststring echo | wc -w
More generally, I might prefer grep [0-9] datafile, but I can't use
that.
But in my first example, what if I didn't know a priori the first
character string?
On Sep 24, 5:34 pm, prelim_questi...@yahoo.com wrote:
> I need to perform a complicated (for me) operation at the command line
> using a series of pipes, but not using grep, sed, or awk.
>
> At one point I may have a list as follows:
>
> 1.2
> 3.45
> 6.7
> a
> bc
>
> Is there an easy way to count only the numeric lines? I do not know
> in advance how many lines are numbers and how many are strictly
> alphabetic. There are no mixed lines.
>
> Thanks in advance.
| |
| Chris McDonald 2007-09-24, 7:23 pm |
| prelim_questions@yahoo.com writes:
>Ok. I think for my purpose I can use: >> ... | sort | xargs
>-E firststring echo | wc -w
>More generally, I might prefer grep [0-9] datafile, but I can't use
>that.
>But in my first example, what if I didn't know a priori the first
>character string?
A pattern for a switch statement in the shell?
(personally I find these contrived homework exercises, where you must
perform a task but may not use the generally agreed upon best tools or
approaches, to be rather, well, contrived. They are generally only set
to stroke the ego of the professor who has 'invented' an alternative
approach. Challenge them - ask *why* you can't use the best approaches.)
________________________________________
______________________________________
Dr Chris McDonald E: chris@csse.uwa.edu.au
Computer Science & Software Engineering W: http://www.csse.uwa.edu.au/~chris
The university of Western Australia, M002 T: +618 6488 2533
Crawley, Western Australia, 6009 F: +618 6488 1089
| |
| Måns Rullgård 2007-09-24, 7:23 pm |
| prelim_questions@yahoo.com writes:
> I need to perform a complicated (for me) operation at the command line
> using a series of pipes, but not using grep, sed, or awk.
>
> At one point I may have a list as follows:
>
> 1.2
> 3.45
> 6.7
> a
> bc
>
> Is there an easy way to count only the numeric lines? I do not know
> in advance how many lines are numbers and how many are strictly
> alphabetic. There are no mixed lines.
This task is so stupid that I'll answer it even though it's homework.
---8<---
c=0
while read line; do
test "${line#*[^0-9.]}" = "$line" && c=$(expr $c + 1)
done < datafile
echo $c
--->8---
There, I bet that wasn't what the instructor had in mind. Counting
alphabetic lines is left as an exercise for the reader, as is checking
that there is at most one decimal point per line.
--
Måns Rullgård
mans@mansr.com
| |
| Soeren Sandmann 2007-09-25, 1:29 am |
| prelim_questions@yahoo.com writes:
> Is there an easy way to count only the numeric lines? I do not know
> in advance how many lines are numbers and how many are strictly
> alphabetic. There are no mixed lines.
This:
.... | ((xargs printf "%f" > /dev/null) 2> /dev/null) && echo fish) | wc -l
should work, but maybe it's cheating since it essentially uses printf
as a poor man's grep.
| |
| Barry Margolin 2007-09-25, 1:29 am |
| In article <fd9dfr$bv1$1@enyo.uwa.edu.au>,
Chris McDonald <chris@csse.uwa.edu.au> wrote:
> prelim_questions@yahoo.com writes:
>
>
>
>
>
> A pattern for a switch statement in the shell?
>
>
> (personally I find these contrived homework exercises, where you must
> perform a task but may not use the generally agreed upon best tools or
> approaches, to be rather, well, contrived. They are generally only set
> to stroke the ego of the professor who has 'invented' an alternative
> approach. Challenge them - ask *why* you can't use the best approaches.)
Because they're trying to teach you particular features of the shell,
such as while loops and case statements, or specific other tools.
Imagine you're taking a swimming class, and the teacher tells you to
practice doing laps doing the backstroke. Would you ask why you can't
do a crawl, since it's a much more efficient way to get across the pool?
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
| |
| Måns Rullgård 2007-09-25, 7:31 am |
| Barry Margolin <barmar@alum.mit.edu> writes:
> In article <fd9dfr$bv1$1@enyo.uwa.edu.au>,
> Chris McDonald <chris@csse.uwa.edu.au> wrote:
>
>
> Because they're trying to teach you particular features of the shell,
> such as while loops and case statements, or specific other tools.
If that's the intent, the examples should be ones where using those
constructs make sense. Otherwise the student will have learned
nothing useful at all.
--
Måns Rullgård
mans@mansr.com
| |
| David Schwartz 2007-09-26, 7:31 am |
| On Sep 24, 11:14 pm, Barry Margolin <bar...@alum.mit.edu> wrote:
> Because they're trying to teach you particular features of the shell,
> such as while loops and case statements, or specific other tools.
Would you teach someone how to use a hammer by telling him to use it
to put in a screw?
> Imagine you're taking a swimming class, and the teacher tells you to
> practice doing laps doing the backstroke. Would you ask why you can't
> do a crawl, since it's a much more efficient way to get across the pool?
Well, in real life, there are races where you must do the backstroke.
Practicing doing the backstroke is helpful for this real life
activity. If there were some corresponding real life situation this
exercise prepared you for, it would be perfectly reasonable.
DS
| |
| Rainer Weikusat 2007-09-26, 7:31 am |
| David Schwartz <davids@webmaster.com> writes:
> On Sep 24, 11:14 pm, Barry Margolin <bar...@alum.mit.edu> wrote:
>
> Would you teach someone how to use a hammer by telling him to use it
> to put in a screw?
The problem can be solved using general programming constructs and it
can be solved by using code written by someone else which in turn uses
general programming constructs. So, a better question would be 'Could
you teach someone how to program an algorithm by having him memorize
quirks and idiosyncrasies of specific (GNU-)programs happening to
implement it?'.
| |
| Stephane CHAZELAS 2007-09-26, 7:20 pm |
| 2007-09-24, 14:34(-07), prelim_questions@yahoo.com:
> I need to perform a complicated (for me) operation at the command line
> using a series of pipes, but not using grep, sed, or awk.
>
> At one point I may have a list as follows:
>
> 1.2
> 3.45
> 6.7
> a
> bc
>
>
> Is there an easy way to count only the numeric lines? I do not know
> in advance how many lines are numbers and how many are strictly
> alphabetic. There are no mixed lines.
[...]
If it has to be convoluted and not obvious and not legible, you
could do things like:
< list tr -cs 0-9. '[\n*]' | wc -l
of course, that doesn't work if there are lines containing both
alphabetics and numbers, or lines with digits and several dots...
--
Stéphane
| |
| Stephane CHAZELAS 2007-09-26, 7:20 pm |
| 2007-09-26, 20:06(+00), Stephane CHAZELAS:
> 2007-09-24, 14:34(-07), prelim_questions@yahoo.com:
> [...]
>
> If it has to be convoluted and not obvious and not legible, you
> could do things like:
>
> < list tr -cs 0-9. '[\n*]' | wc -l
>
> of course, that doesn't work if there are lines containing both
> alphabetics and numbers, or lines with digits and several dots...
And to *not* reply to the question, I think the most obvious
solution should be something like:
LC_ALL=C grep -xcE '[0-9]*\.?[0-9]+'
or
LC_ALL=C grep -xcE '[-+]?[0-9]*\.?[0-9]+'
LC_ALL=C grep -ixcE '[-+]?[0-9]*\.?[0-9]+e[-+]?[0-9]+'
depending on what exactly is numeric for you.
--
Stéphane
| |
| Barry Margolin 2007-09-27, 2:30 am |
| In article <874phhvjz2.fsf@fever.mssgmbh.com>,
Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
> David Schwartz <davids@webmaster.com> writes:
>
> The problem can be solved using general programming constructs and it
> can be solved by using code written by someone else which in turn uses
> general programming constructs. So, a better question would be 'Could
> you teach someone how to program an algorithm by having him memorize
> quirks and idiosyncrasies of specific (GNU-)programs happening to
> implement it?'.
Thank you.
To David, can you give examples of simple exercises that can only be
done using shell built-in constructs for looping and comparing, but
would not be easier to do using higher-level tools like sed and awk?
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
| |
| Michal Nazarewicz 2007-09-28, 7:30 am |
| > prelim_questions@yahoo.com writes:
Måns Rullgård <mans@mansr.com> writes:[vbcol=seagreen]
> This task is so stupid that I'll answer it even though it's homework.
>
> ---8<---
> c=0
> while read line; do
> test "${line#*[^0-9.]}" = "$line" && c=$(expr $c + 1)
> done < datafile
> echo $c
> --->8---
This however will give a false positive on lines like "." or "42..42"
and false negative on "+42". I'd use case:
#v+
c=0
while read line; do
case "$line" in
(*.*.*|*.|*[!0-9.]*) ;;
esac
done <datafile
echo $c
#v-
This code is intentionally broken as to make OT think, understand and
fix the code before giving it as an answer to the professor. It also
gives false negative on "+42" but it's trivially fixed (hint: use
${foo#...} construct to remove plus or minus sign from the beginning of
variable). This won't consider "4.2e+10" as a numeric.
--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
| |
| Chris F.A. Johnson 2007-09-29, 1:47 am |
| On 2007-09-25, Måns Rullgård wrote:
> prelim_questions@yahoo.com writes:
>
>
> This task is so stupid that I'll answer it even though it's homework.
>
> ---8<---
> c=0
> while read line; do
> test "${line#*[^0-9.]}" = "$line" && c=$(expr $c + 1)
If the shell you are using has $( ... ) for command substitution,
it also has $(( ... )) for arithmetic, and there's no need to use
expr.
> done < datafile
> echo $c
> --->8---
--
Chris F.A. Johnson, author | <http://cfaj.freeshell.org>
Shell Scripting Recipes: | My code in this post, if any,
A Problem-Solution Approach | is released under the
2005, Apress | GNU General Public Licence
|
|
|
|
|