a puzzle

May. 26th, 2008 12:22 am
zwol: ((mad) science)
[personal profile] zwol
Given two shell variables, A and B, each of which is a space-separated list of numbers, how would you iterate over the lists in parallel, comparing each pair? That is, compare number A1 to number B1, A2 to B2, and so on. You may not use features not available on old systems (such as functions, arrays, and local variables) and you may not mess with the positional parameters. Comprehensibility is not important.

Date: 2008-05-26 05:50 am (UTC)
From: [identity profile] aldren.livejournal.com
Given a file 'test.pl' with the following contents:

#!/usr/bin/perl
use warnings;
use strict;
print ($ARGV[0] eq $ARGV[1] ? "Yes\n" : "No\n");


The following bash shell script seems to do the trick on OS X:

TEST=./test.pl
A="3 56 922 1 2 333"
B="73 1 33 -9 2 1"
LENGTH=`echo $A | tr ' ' '\n' | wc -l | sed 's/ //g'`
for OFFSET in `jot $LENGTH 1 $LENGTH`; do
$TEST `echo $A | cut -d' ' -f$OFFSET` `echo $B | cut -d' ' -f$OFFSET`;
done


This script uses jot, but your system might not have jot, so you'll have to use something like seq.

Date: 2008-05-26 05:51 am (UTC)
From: [identity profile] aldren.livejournal.com
Upon further reflection, the 'warnings' and 'strict' probably aren't necessary for the perl script. It's just such a hard habit to break, even for one-liners :)

Date: 2008-05-26 04:22 pm (UTC)

perl is cheating?

Date: 2008-05-26 06:46 am (UTC)
From: [identity profile] tkil.livejournal.com
If you're already positing (POSIXing?) the availability of Perl, then you can do it all in Perl:

perl -lwe 'my @first = split " ", $ARGV[0];
my @second = split " ", $ARGV[1];
my $cmd = $ARGV[2];
while ( @first && @second ) {
system $cmd, shift(@first), shift(@second);
}' "$var1" "$var2" "do stuff with "

Re: perl is cheating?

Date: 2008-05-26 07:07 am (UTC)
From: [identity profile] aldren.livejournal.com
Well, I'm only using perl as the test command. It can be easily swapped out for any test. Here's an example that uses [:


#!/bin/sh
if [ $1 -eq $2 ]; then echo "Yes"; else echo "No"; fi

Re: perl is cheating?

Date: 2008-05-26 04:23 pm (UTC)
From: [identity profile] zwol.livejournal.com
Perl is definitely cheating, which is a shame. Awk isn't (in the actual script I was writing I ended up doing the whole thing in awk) but it's so much nicer in perl.

Date: 2008-05-26 04:22 pm (UTC)
From: [identity profile] zwol.livejournal.com
I've never even heard of jot, but I like the use of cut there. Why not use wc -w, though? That way you don't need the tr with '\n', which is another of the features not available on old systems, unfortunately.

(It's hard to articulate exactly what you can and cannot do in a shell script that has to run on all systems that are still widely enough used to matter. The minimal spec from SUSv2 (not SUSv3 or POSIX-2001) is a baseline, but then you have to enumerate all of the bugs on this or that system. I am oddly pleased that I am no longer as good at this as I used to be.)

Date: 2008-05-26 05:54 pm (UTC)
From: [identity profile] aldren.livejournal.com
You're right, wc -w would be a better choice. I just use that mode so infrequently I forgot it existed.

And even if tr was not available, sed ought to be.

jot came up on my system when I did an apropos seq. I know seq used to be standard on various Unices, but seems to have fallen out of favor, and I'm not quite sure why. Some BSDs ship with seq2 though. You might have to vary the script depending on what's present.

Date: 2008-05-27 07:45 pm (UTC)
From: [identity profile] zwol.livejournal.com
Oh ick. I had been under the impression seq was in at least one of the myriad inconsistent standards that cover these things. If some folks have seq, and others have seq2, and yet others have jot, that boils down to you can't use any of them in this particular context.

Date: 2008-05-30 06:12 am (UTC)
From: [identity profile] aldren.livejournal.com
It seems as though seq (sometimes called seq2 or gseq) is a GNU/Linux-ism, whereas jot is more for FreeBSD systems (which is why it's on OS X.) An interesting solution is to roll your own seq:

yes '' | head -n $LENGTH | nc -ba

Or, on systems that don't have yes (which, apparently, isn't a POSIX command,):

dd < /dev/zero 2>&- ibs=1 cbs=1 count=$LENGTH conv=unblock | sed -n = (stolen from here, but now added to my bag-of-tricks.)

Date: 2008-06-02 07:27 am (UTC)
From: (Anonymous)
You added it to your bag of tricks? You have _got_ to be kidding!?

Date: 2008-05-27 07:39 pm (UTC)
From: [identity profile] silverhawk.livejournal.com
And sometimes I wonder if people are speaking another language.

I suddenly have a strange feeling I know what my cadets were thinking all semester.

Date: 2008-05-27 07:43 pm (UTC)
From: [identity profile] zwol.livejournal.com
Could you unpack that a little? I should hate to think your cadets were applying the requirements of the specific situation I was stuck in the other day (which I feel oddly compelled not to explain), to anything else...

Date: 2008-05-27 08:04 pm (UTC)
From: [identity profile] silverhawk.livejournal.com
Basically, I read through the "course end feedback" today. There were a lot of comments (well, one or two) along the lines of "she really knew what she was talking about. Pity we couldn't understand it."

I got that feeling reading your post. I was talking about math. You were apparently talking about shell scripting. I don't even know what you were asking.

Date: 2008-05-27 08:44 pm (UTC)
From: [identity profile] zwol.livejournal.com
Aha, I see how you mean. (I've received equivalent comments in my own TA feedback forms, sad to say.) Here I was deliberately being cryptic, though, both in the problem statement and in avoiding any discussion of why one might want to do this odd thing.

April 2017

S M T W T F S
      1
2345678
9101112131415
16171819 202122
23242526272829
30      

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 3rd, 2026 12:51 am
Powered by Dreamwidth Studios