1

The situation is as following: I have a .txt file that includes series of letters all divided bij newlines Here's a small part of the file:

lrtjxz
lrtjhs
lrtsxv
lrtvsw
lrtywj
lrtyws
lrxwwv
lrvhsx
lryjts
lrytwv
lrzvwj
lzwscr
lzjrww
lzjroj
lzjrvs
lzjrhs
lzojvs

I created a script that would count the number of times one of these lines is alphabetically ordered. But for some reason it echo's nothing not even 0.

Script:

cat file.txt | while read line
do
alphabeticSorted=$(echo $line | grep -o . | sort)
if [ "$line" == "$alphabeticSorted" ]
then
count=$((count + 1))
fi
done

echo "$newCount"

Does anyone know what I am doing wrong?

user147290
  • 11
  • 1
  • 2
  • 1
    Welcome to Unix SE, as the link to the possible duplicate question highlights, the trouble is with the pipe. When you create a pipe the different parts end up in subshells, and a subshell cannot change the parent's variables. You can rewrite that loop to avoid a pipe though by using input redirection – Eric Renouf Dec 13 '15 at 16:33
  • 1
    Note that the way the script is written right now $alphabeticSorted will never equal $line for input like "abcdef" due to the newlines inserted by grep -o .. – nwk Dec 13 '15 at 16:41
  • 1
    Your code could also be improved by removing the UUOC (Useless Use of Cat) – fpmurphy Dec 13 '15 at 20:56

1 Answers1

1

There are actually two different issues, and both contribute to the outcome of no echo.

Here are the details:

Bad comparison

You wrote:

alphabeticSorted=$(echo $line | grep -o . | sort)
if [ "$line" == "$alphabeticSorted" ]
  • grep -o puts each match on its own per line
  • . matches a single individual character
  • the original line has characters horizontally
  • but the grep -o places characters "vertically"
  • so the original $line is never going to equal the after-grep line

For example, on command prompt you can test this:

$ line="abc"

Now see what the original $line contains:

$ echo "$line"
abc

Now see how grep -o changes it, and this is basically your $alphabeticSorted

$echo "$line" | grep -o .
a
b
c

So remember you wrote this:

if [ "$line" == "$alphabeticSorted" ]

So what Bash is actually testing is, does:

abc

equal to

a
b
c

Well as you can see it is not the same thing, so your if statement would never be true even if your original $line was perfectly alphabetical.

I would highly recommend making them both the same orientation, either both horizontal or both vertical. Let us do both horizontal, so you can test in Bash

$ line2=$( echo $line | grep -o . | sort | tr -d '\n'

$ echo $line2
abc
  • we add tr command, the -d to delete something, and the something, being new lines \n
  • thus the $line2 is "horizontal" just like the $line1

So in your original code if you just modify it so

alphabeticSorted=$(echo $line | grep -o . | sort | tr -d '\n')

if [ "$line" == "$alphabeticSorted" ]

It should now be a more reasonable comparison.

Wrong variable

But even if you fix this, there is a second problem with your posted script, which is you have this in the body of your code:

count=$((count + 1))

But you are not referring to $count at all, you said you wrote:

echo "$newCount"

Because there is no $newCount defined, of course when calling this, there is no value, it is nothing, so you get nothing. What you probably wanted was:

echo "$count"

So with those two bugs addressed, as far as I can tell from the code provided, it should now work.

clarity123
  • 3,539