I always forget the syntax of command-line tools for searching through multiple files. What's the easiest/fastest way to search through, say, all of the .sty
files distributed in TeX Live for the occurrence of a string, say, \everypar
? (Let's assume Linux/Mac OS X.)
4 Answers
I'm using a script called texgrep
like this:
texgrep everypar sty
backslashes should be quoted. Here's the source of the script:
Search pattern:
#!/bin/bash
# texgrep - searches for a text pattern contained in files
# located inside the texmf trees
# usage: texgrep pattern [extension]
# usage examples:
# texgrep phantomsection sty
# texgrep \\\\def\\\\phantomsection
if [ $# -eq 0 ]; then
echo 1>&2 Usage: texgrep pattern [extension]
exit 1
fi
for path in TEXMFMAIN TEXMFDIST TEXMFHOME
do
find `kpsewhich --var-value=$path` -type f -name "*$2" |xargs grep $1
done
exit 0
It's valuable for me because I like to read sources and this saves me time. I've put the script on my blog some time ago: Speed up the work by shell scripts.
More scripts related to search & work:
Search and edit:
#!/bin/bash
# texedit - find one or several tex related files
# and open them in the editor
if [ $# -eq 0 ]; then
echo 1>&2 Usage: texedit file1 [file2] ...
exit 1
fi
gedit `kpsewhich $@`
exit 0
Search and look around:
#!/bin/bash
# texls - list the content of the directory
# corresponding to a certain tex related file
if [ $# -eq 0 ]; then
echo 1>&2 Usage: texls filename [pattern]
echo 1>&2 examples: texls babel.sty
echo 1>&2 texls book.cls *clo
exit 1
fi
ls `kpsewhich $1 | sed 's/\(.*\)\/.*$/\1\//'`$2
exit 0
Search and change to directory:
#!/bin/bash
# texcd - change into the directory
# corresponding to a certain tex related file
if [ $# -eq 0 ]; then
echo 1>&2 Usage: . texcd filename [pattern]
echo 1>&2 examples: . texcd beamer.cls
exit 1
fi
cd `kpsewhich $1 | sed 's/\(.*\)\/.*$/\1/'`
echo Changed to: `pwd`
All could be done by shell functions instead of scripts. Like Michael suggested in my blog:
function texcd ()
{
cd $(dirname "$(kpsewhich "$1")");
}
I hope it's useful for somebody, even though it goes beyond the question.
-
These are great! Briefly trying Willie's suggestion to use grep instead of find seems to show a significant speedup, if you're interested. Oct 14, 2010 at 7:50
Well, my command lines tend to be quite verbose, but I think you could search for all occurances of foo
in sty
files on $TEXMF
by:
for texmf in `kpsewhich -expand-path '$TEXMF' | sed 's/:/ /g'`; do
find $texmf | grep '\.sty$' | xargs -J% grep -n 'foo' %;
done
Now that I've had my morning vat o' coffee (and read some comments), a more concise version would be:
grep -r --include=*.sty -n '\\everypar' `kpsewhich -expand-path '$TEXMF' | sed 's/:/ /g'`
This is what I do:
ack --tex '\\everypar' /opt/texlive2010
has really nice output (and a TextMate bundle as well - but that's not the question) and is quite fast. Make sure you've got everything you need in the --tex
part by setting in the ~/.ackrc
or on the command line something like this:
--type-set=tex=.tex,.sty
(you should also include .mkiv
and .mkii
, you know ;-))
-
I forgot:
ack
is a replacement forgrep -r
. See the ack homepage for more info.– topskipOct 13, 2010 at 18:10 -
-
1
It is slightly easier for ConTeXt. Just enter your search phrase in the search box here
find
is your friend here.grep -r --include=*.sty "\\everypar" <DIR>
(Need to escape the backslash.)