grepping a fixed string at the beginning of a line

If you only need to check whether or not a match is found, cut all input lines to the length of the desired prefix ($1) and then use fixed-pattern grep:

if cut -c 1-"${#1}" | grep -qF "$1"; then
    echo "found"
else
    echo "not found"
fi

It's also easy to get the count of matching lines:

cut -c 1-"${#1}" | grep -cF "$1"

Or the line numbers of all matching lines (line numbers start at 1):

cut -c 1-"${#1}" | grep -nF "$1" | cut -d : -f 1

You could feed the line numbers to head and tail to get the full text of the matching lines, but at that point it's easier to just reach for a modern scripting language like Python or Ruby.

(The above examples assume Posix grep and cut. They assume the file to search comes from standard input, but can easily be adapted to take a filename instead.)

Edit: You should also ensure that the pattern ($1) is not a zero-length string. Otherwise cut fails saying values may not include zero. Also, if using Bash, use set -o pipefail to catch error-exits by cut.


A way using perl which will respect backslashes

v="$1" perl -ne 'print if index($_, $ENV{"v"} )==0' file

This sets the environment variable v for the command, then prints if the index of the variable is 0 i.e the beginning of the line.

You can also do identical in awk

v="$1" awk 'index($0, ENVIRON["v"])==1' file

I can't think of a way to do this using grep; ^ itself is part of a regular expression so using it requires regular expressions to be interpreted. It's trivial using substring matching in awk, perl or whatever:

awk -v search="$1" 'substr($0, 1, length(search)) == search { print }'

To handle search strings containing \, you can use the same trick as in 123's answer:

search="$1" awk 'substr($0, 1, length(ENVIRON["search"])) == ENVIRON["search"] { print }'

Tags:

Grep