15

I'm looping over lines in a file. I just need to skip lines that start with "#". How do I do that?

 #!/bin/sh 

 while read line; do
    if ["$line doesn't start with #"];then
     echo "line";
    fi
 done < /tmp/myfile

Thanks for any help!

1
  • Now in bash when using -i, it will use interactive_comments.
    – An5Drama
    Commented Apr 7 at 8:22

2 Answers 2

21
while read line; do
  case "$line" in \#*) continue ;; esac
  ...
done < /tmp/my/input

Frankly, however, it is often clearer to turn to grep:

grep -v '^#' < /tmp/myfile | { while read line; ...; done; }
6
  • You could also do something too clever with expr or suffix removal (e.g., [ -z "${line%%#*}" ]), but these would be equally or less readable than the case option, I think.
    – pilcrow
    Commented Sep 19, 2012 at 4:43
  • 2
    To also strip lines where whitespace (only) precedes #, use grep -v '^\s*#' < /tmp/myfile instead - this is in line with the case solution, given that read strips leading and trailing whitespace.
    – mklement0
    Commented Sep 19, 2012 at 4:59
  • 4
    Another option (if for some reason someone wanted to avoid grep) might be if [[ $line =~ ^# ]]; then continue; fi. Commented Sep 19, 2012 at 6:50
  • 2
    The grep solution won't work if the while loop needs to modify variables in the current shell, as the loop runs in a subshell (unless bash 4.2 is available and set -o lastpipe is used). Other shells may run the while loop in the current shell by default.
    – chepner
    Commented Sep 19, 2012 at 12:32
  • 8
    Another option is [[ $line = \#* ]] && continue.
    – chepner
    Commented Sep 19, 2012 at 12:32
1

This is an old question but I stumbled upon this problem recently, so I wanted to share my solution as well.

If you are not against using some python trickery, here it is:

Let this be our file called "my_file.txt":

this line will print
this will also print # but this will not
# this wont print either
      # this may or may not be printed, depending on the script used, see below

Let this be our bash script called "my_script.sh":

#!/bin/sh

line_sanitizer="""import sys
with open(sys.argv[1], 'r') as f:
    for l in f.read().splitlines():
        line = l.split('#')[0].strip()
        if line:
            print(line)
"""
echo $(python -c "$line_sanitizer" ./my_file.txt)

Calling the script will produce something similar to:

$ ./my_script.sh
this line will print
this will also print

Note: the blank line was not printed

If you want blank lines you can change the script to:

#!/bin/sh

line_sanitizer="""import sys
with open(sys.argv[1], 'r') as f:
    for l in f.read().splitlines():
        line = l.split('#')[0]
        if line:
            print(line)
"""
echo $(python -c "$line_sanitizer" ./my_file.txt)

Calling this script will produce something similar to:

$ ./my_script.sh
this line will print
this will also print


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