Friday, May 8, 2015

macos - grep says 'invalid character range'



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


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.


No comments:

Post a Comment