Grep – Fix ‘Invalid Character Range’ Error

bashfindgrepmacos

So I'm using a combination of find and grep to filter out a list of file names from a plain text document.

Here's the command I run:

find /Volumes/Documents\ -\ Part\ 1/July 2009 -type f | grep -vf files.txt

In files.txt I have this:

/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages

I want it to output any non-matching lines, but instead I get this:

grep: invalid character range

What is the cause of this? There is a lot more to files.txt, I just omitted it because it would be too long. I do have several unicode characters in there, too. Could that be causing any issues?

Mac OS X Yosemite, bash 3.2.57(1)-release, grep (BSD grep) 2.5.1-FreeBSD

Best Answer

TLDR; add -F


The -f option of grep is used to refer to a file that contains a list of patterns - your file does not contain a list of patterns it contains a list of filenames

man grep

-f FILE, --file=FILE Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore matches nothing. (-f is specified by POSIX.)

You need to make sure any metacharacters in your filenames are escaped unless you want them to be treated as metacharacters.


$ cat files.txt
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages

$ echo a | grep -vf files.txt
a

It seems to me your files.txt probably contains more than the four lines you show.

Check the file using

$ wc files.txt
  4  21 221 files.txt

$ sum files.txt
43924     1

If in doubt, use the -F option (uppercase F) - but then you don't escape metacharacters in file.txt.

Note the following

$ cat files.txt
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
[z-a]

$ echo aaa | grep -vf files.txt
grep: Invalid range end

$ echo aaa | grep -Fvf files.txt
aaa

The -F option tells grep that your search patterns contain no regular expressions and that it should treat them as plain text.

Related Question