Need help how to search for shortest line from a file

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted!

  1. The problem statement, all variables and given/known data:
    I have to write a program that have to read every standard input then print out the line number and the content of longest line and shortest line.

So, far I have figured out the to find the longest line from the input file and still searching for the hints of what command to use for finding the shortest line.

Would someone would give me a hint for that?

Thanks in advance,

Scopiop

  1. Relevant commands, code, scripts, algorithms:
cat -n inputfile

     1  The combination of bold design.
     2  Other on-board perks include a 20% increase in capacity per train.
     3  The new design was
     

output

2:Other on-board perks include a 20% increase in capacity per train.
  1. The attempts at a solution (include all code and scripts):
egrep -n "^.{$(wc -L < inputfile)}$" inputfile
  1. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course):

City College of San Francisco/Aaron Brick/160B
Note: Without school/professor/course information, you will be banned if you post here! You must complete the entire template (not just parts of it).

As we are not allowed to provide full solutions in the homework sub-forum, I suggest following code (you can build upon):

linenumber=1

while read line; do
 echo "line length" "line number" "$line" # hint for line length: ${#parameter}
 # increment line number by one here, hint: $((expression))
done < inputfile > outputfile # everything you echoed above goes to the outputfile
  1. Go through the inputfile line by line in a while loop
  2. Print line length, line number and line
  3. Afterwards you get the longest and shortest line by utilizing (hint: using pipes) following tools on the outputfile:
    sort -n , head / tail -n1 and cut -d' ' -f2- (check out the man pages of the particular tools to learn the meaning of the options I mentioned for the particular tool)

Hope this helps.

I'm pretty sure the output you have given is NOT the result of the code you have presented.

What tools (e.g. awk) are allowed? It can be done with only shell (bash) builtins (while loop, read, parameter expansion, arithmetic evaluation).

EDIT: and junior-helper has given you hands-on examples for above...

Thank you Junior-helper and RudiC.

I have ran in the problem since the instructor does not allow me to send my output to another file and read back in again. He prefers that the program will output max and min lines without using a temp file. Therefore, I rewrote my program by using many if elif and else statement to filter out all lines as possible to find the max and min lines. But I apparently ran into a problem. If the blank line has a space, which will be my shortest line is 1 character but display is nothing. There fore I want to filter out the blank space which is equivalent as a blank line. To set a space in one of my elif statement, how do I do that? I have tried

 
elif ((${#line} != '  ' )) 
#also 
elif (($#line} != " " ))

it was unsuccessful to resolve my problem
inputfile

Why first
 
hello
 
I don't have any idea

now what it is
I am very sure the output out have given is NOT the result of the code you have presented.

output

The longest line is 90 characters long line# 8: I am very sure the output out have given is NOT the result of the code you have presented.

The shortest line is 1 characters long line# 2:

Thanks in advance,

Scopiop

${#line} will hold the line lenght, eg. 90. That is the reason why ${#line} != ' ' is not going to work.

HINT: If the line is a "real" blank line (no spaces at all) or is a blank line *with* spaces and/or tabs only, ${#line} will always be 0.

# filtering out "real" blank lines (without spaces and/or tabs)
# AND/OR blank lines with spaces and/or tabs
if [ ${#line} -ne 0 ]
 then
 # perform your checks here only on lines with length != 0 (non-blank lines).
fi

Does it help you further?

I have tried to test the input file that has 1 blank includes with 2 characters SPACE and here the result.

 
if [[ ${#line} > $maxline && ${#line} != 0 ]]

input

            <-- it's blank here with 2 SPACE characters

output

 Standard input only have one line therefore only one line output

The longest line is 2 characters long line# 1:

That seems not to produce the expected output :confused:

$ while read line; do if [[ ${#line} > 10 && ${#line} != 0 ]]; then echo ${#line}; fi; done <inputfile 
9
5
21
14
90

Try

if [[ ${#line} -gt $maxline && ${#line} != 0 ]]

you can see my attachfile to run my codes

Here is how the instructor want us run the program

$ cat inputfile | program.sh

Please create an inputfile that contains a blank line with a few SPACE characters in it. You will see what I mean.

Thank you,

Scopiop

./linelengthhw2vs2.sh: line 34: -r: command not found

It should be while IFS= read -r line
If you reset IFS (IFS=), then all I said before, namely ${#line} is always 0 on blank lines, is not valid anymore!!
With IFS= the leading spaces are preserved and thus counted.

If you want to keep IFS= then put following immediately after the do command: line=${line## *}
That will delete all leading spaces.

When you change that, your script should perform much better:

$ cat testfile
123
      <- here are 5 spaces
abcde
aaaaaaaaa
   <- here are 2 spaces
aaaaaa
$ cat testfile | ./linelength.sh 
line either blank or between max or min
line either blank or between max or min
The longest line is 9 characters line:  4 contents aaaaaaaaa
The shortest line is 6 characters line:  6 contents aaaaaa
$ 

You see, the blank lines are properly recognized, but there is another "bug" in the report of the shortest line. The shortest line is line 1.

I enabled the debugging option in the script set -x

      -x  Print commands and their arguments as they are executed
$ cat testfile | ./linelength.sh 
+ linecount=1
+ maxlinechars=0
+ minlinechars=0
+ maxcontents=0
+ mincontents=0
+ maxlinenumber=0
+ minlinenumber=0
+ IFS=
+ read -r line
+ line=123
+ ((  3 > 0  ))
+ maxlinechars=3           #
+ maxcontents=123          # OK, you stored the values for the first string as longest string. So far, so good.
+ maxlinenumber=1          #
+ (( linecount++ ))
+ IFS=
+ read -r line
+ line=
+ ((  0 > 3  ))
+ ((  0 == 0 && 0 != 0  ))
+ ((  0 < 0 && 0 != 0  ))
+ echo line either blank or between max or min
line either blank or between max or min
+ (( linecount++ ))
+ IFS=
+ read -r line
+ line=abcde
+ ((  5 > 3  ))
+ maxlinechars=5           # Next line is longer than the previous one...
+ maxcontents=abcde        # At this moment, line number 1 has the shortest string, but that's somehow ignored here
+ maxlinenumber=3          # and leads to an incorrect report at the end.
+ (( linecount++ ))
...

Hope this helps.

Thanks, I remove the IFS and it solved all my problem. I did not need to use FIELD SEPARATOR in this case of reading.... Thank you much.

scopiop