41

I have a shell script like this:

cat file | while read line
do
    # run some commands using $line    
done

Now I need to check if the line contains any non-whitespace character ([\n\t ]), and if not, skip it. How can I do this?

planetp
  • 14,248
  • 20
  • 86
  • 160

7 Answers7

85

Since read reads whitespace-delimited fields by default, a line containing only whitespace should result in the empty string being assigned to the variable, so you should be able to skip empty lines with just:

[ -z "$line" ] && continue
Arkku
  • 41,011
  • 10
  • 62
  • 84
  • 5
    (More accurately, the delimiter used by `read` is determined by the `IFS` variable, which defaults to whitespace. Just unset `IFS` to revert to using whitespace.) – Arkku Apr 05 '10 at 12:23
  • 2
    even simpler: no need to quote line, if you use bash's [[ syntax: `[[ -z $line ]] && continue` – pihentagy Oct 10 '13 at 16:08
  • 3
    @pihentagy Umm, that has the same number of characters, and the square brackets `[]` are harder to type than quotes on some international keyboards, and it becomes bash-specific. So maybe not simpler, but an alternative. =) – Arkku Oct 11 '13 at 12:14
  • 5
    (for those newbie like me). `[ -z "$line" ] && continue` itself is executable. This elegant line is equivalent to `if [ -z "$line" ] ; then continue ; fi`. By the way, don't forget to set `IFS=" \t\n"` at the beginning unless you don't want to skip 'tab'. – Xin Cheng Apr 17 '19 at 16:24
  • re. suggested edits that add things, please post your own answers instead – this answers the original question as it is, and works quite universally regardless of the shell, so I don't think the answer is improved by complicating it with more cases for specific shells and/or needs beyond the original question – Arkku Nov 20 '20 at 14:25
18

try this

while read line;
do 

    if [ "$line" != "" ]; then
        # Do something here
    fi

done < $SOURCE_FILE
Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
NSC
  • 181
  • 1
  • 2
  • 1
    More information about the square bracket notation can be found at [the man page of test](http://man.cx/test) – c0dem4gnetic Oct 16 '12 at 18:35
  • disadadvantage here: If the part in the if is long, you get a code difficult to read. Therefore the continue solution is always recommended. – Timo Nov 18 '20 at 17:01
7

bash:

if [[ ! $line =~ [^[:space:]] ]] ; then
  continue
fi

And use done < file instead of cat file | while, unless you know why you'd use the latter.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • I need smth that would work in both bash and sh. Is there any solution using sh/sed/tr (in case bash is not installed)? – planetp Apr 05 '10 at 11:41
  • 1
    This worked, the other ([ -z "$line" ] && continue) did not work. I wonder why. – Timo Nov 18 '20 at 17:21
2

cat i useless in this case if you are using while read loop. I am not sure if you meant you want to skip lines that is empty or if you want to skip lines that also contain at least a white space.

i=0
while read -r line
do
  ((i++)) # or $(echo $i+1|bc) with sh
  case "$line" in
    "") echo "blank line at line: $i ";;
    *" "*) echo "line with blanks at $i";;
    *[[:blank:]]*) echo "line with blanks at $i";;
  esac
done <"file"
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
1
if ! grep -q '[^[:space:]]' ; then
  continue
fi
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0
blank=`tail -1 <file-location>`
if [ -z "$blank"  ]
then
echo "end of the line is the blank line"
else
echo "their is something in last line"
fi
NickCoder
  • 1,504
  • 2
  • 23
  • 35
Rounak
  • 1
0
awk 'NF' file | while read line
do
    # run some commands using $line    
done

stole this answer to a similar question: Delete empty lines using sed