Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have the following testfile.txt:

string1 1  
string2 2  
string3 3  
string1 2  
string2 4  
string3 6  
string1 3  
string2 6  
string3 9  

I have the following script:

#!bin/sh

oldstr="abc"  
while read line  
do  
    newstr=\`echo "$line" | sed 's/\(.*\)\( \)\([0-9].*\)/\1/'\`
    echo "$oldstr vs $newstr"

    if [ $oldstr == $newstr ] 
    then 
       echo "old $oldstr"
    else
       oldstr=$newstr
       echo "new $oldstr"
    fi
done < $@ | sort
echo "done"

I then run the script:

$ sh test.sh testfile.txt

and get the output:

abc vs string1  
new string1  
new string1  
new string1  
new string2  
new string2  
new string2  
new string3  
new string3  
new string3  
string1 vs string2  
string1 vs string2  
string1 vs string2  
string2 vs string3  
string2 vs string3  
string2 vs string3  
string3 vs string1  
string3 vs string1  
done

I'd like to know why, as I would expect the output to be:

abc vs string1  
new string1  
string1 vs string1
old string1  
string1 vs string1
old string1  
string1 vs string2
new string2  

and so on.

  1. Why isn't the "if" statement working?
  2. Why is the echo printing out of sequence?
share|improve this question
    
I understand that the question is quite basic --- but I really do not understand the downvote without any comment. At least a link to RTFM should be given. –  Rmano Jan 21 at 2:59

1 Answer 1

up vote 3 down vote accepted

1) they are out of order because you asked it: you prepare the whole list and then | sort them.

2) the test should be (standard sh syntax): if [ "$variable" = ... (not ==).

3) to test things, use sh -xv which will print every line before executing it and the result of expansions.

4) why do you escape the backticks?

5) You've got missing quotes around your variables

6) < $@ only works if there's only one argument to the script.

7) using read without -r and without removing the whitespace characters from $IFS probably doesn't make sense here.

8) you can't use echo with arbitrary data

9) It should be #!/bin/sh, not #!bin/sh

Working script:

#!/bin/sh 

oldstr="abc"  
while IFS= read -r line  
do  
    newstr=`printf '%s\n' "$line" | sed 's/\(.*\)\( \)\([0-9].*\)/\1/'`
    printf '%s\n' "$oldstr vs $newstr"

    if [ "$oldstr" = "$newstr" ] 
    then 
       echo "old $oldstr"
    else
       oldstr=$newstr
       printf '%s\n' "new $oldstr"
    fi
done < "$1" 

echo "done"

Moreover, you should change the input test file. The one you posted never triggers the "old" case.

If you want to sort the file before passing it to the loop, change the while line to:

sort -- "$@" | while IFS= read -r line 

and obviously remove the < $@ after done:

sort -- "$@" | while IFS= read -r line  
do  
   [...]
done
share|improve this answer
    
What I wanted to do was sort the file before passing it to the while loop. I realized what the code was actually doing was to pass the file to the while loop, which processed it and then piped it to the sort, not exactly what I want! How do I sort the file before passing it to the while loop? –  EggHead Jan 21 at 2:06
    
Thanks, it is the answer I'm looking for! –  EggHead Jan 21 at 3:45
    
I strongly disagree on the it would be much better to use bash for scripting. –  Stéphane Chazelas Jan 21 at 7:48
    
@StephaneChazelas you are right that this is a personal preference --- I have removed it. Thanks for the edit --- useful corrections (I was lazy). –  Rmano Jan 21 at 15:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.