0

can anyone give a look to this bash script of mine please? I am trying to find the longest line in a file using a bash script so I wrote this.

#!/bin/bash

#Francesco Foschi length of a row in a file

let n=0
let max_length=0

while read row
do
    length=$(echo -n $row | wc -c)
    if[ ${#length} -gt ${#max_length} ]
    then
            let max_length=${#length}
    fi

    echo "$n row is $length charachters long"
    echo "$row"
    let n=n+1

done < $1

echo "longest line is $max_length charachters long"

exit 0

Every time I try to run the console says that I have a syntax error near the unexpected then token. What am I doing wrong??

BTW running of fedora28

tripleee
  • 175,061
  • 34
  • 275
  • 318
francesco foschi
  • 323
  • 1
  • 2
  • 9
  • 2
    You should put a space after the word `if`. – Robin Green Nov 24 '18 at 16:00
  • 4
    I suggest you to check your code in https://www.shellcheck.net/ – ingroxd Nov 24 '18 at 16:22
  • `length="${#row}"` – Cyrus Nov 24 '18 at 17:19
  • Bash is a supremely slow and tacky tool for this particular task. You want to investigate reimplementing the script in Awk for any real-world scenario. – tripleee Nov 26 '18 at 05:56
  • I rolled back your latest edit. Questions on Stack Overflow should remain strictly questions; the way to mark something as a suitable answer is simply to accept an answer, like you already did. (The [question's edit history](/posts/53459879/revisions) still contains all the text if you want to recover it.) – tripleee Nov 26 '18 at 05:57
  • Also check the spelling of *"characters"*. – tripleee Nov 26 '18 at 05:58

3 Answers3

5

GNU wc has this functionality built in:

-L, --max-line-length
        print the maximum display width
cody
  • 11,045
  • 3
  • 21
  • 36
2

try this:

#!/bin/bash
#Francesco Foschi length of a row in a file

let n=0
let max_length=0

while read row
do
    length=$(echo -n $row | wc -c)
    if [ ${length} -gt ${max_length} ]
    then
            let max_length=${length}
    fi

    echo "$n row is $length charachters long"
    echo "$row"
    let n=n+1

done < $1

echo "longest line is $max_length charachters long"

exit 0
gopy
  • 328
  • 1
  • 9
2

plain bash

#!/bin/bash
max=-1
while IFS= read -r line; do
    [[ ${#line} -gt $max ]] && max=${#line}
done < "$1"
echo "longest line is $max chars long"

This idiom is used to read the line exactly verbatim: IFS= read -r line

Demo:

  1. create a file with leading/trailing whitespace and a backslash

    $ echo ' h\bHello ' > file
    

    this file is 10 bytes in size (not counting the trailing newline).

  2. read it with plain read var

    $ read line < file; printf %s "$line" | od -c
    0000000   h   b   H   e   l   l   o
    0000007
    

    Only 7 chars: missing the backslash and the whitespace

  3. add the -r option for read:

    $ read -r line < file; printf %s "$line" | od -c
    0000000   h   \   b   H   e   l   l   o
    0000010
    

    Now we have 8 characters (the "0000010" is octal), but still missing the whitespace.

  4. add the IFS= variable assignment:

    $ IFS= read -r line < file; printf %s "$line" | od -c
    0000000       h   \   b   H   e   l   l   o    
    0000012
    

    10 characters (octal 12): now we have exactly what was written to the file in $line.

It's a pain to have to write IFS= read -r line all the time, but bash inflicts considerable pain on the programmer.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352