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.)
- 73,872
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.
- 3,620
- 231,401
-
1These are great! Briefly trying Willie's suggestion to use grep instead of find seems to show a significant speedup, if you're interested. – Will Robertson Oct 14 '10 at 07: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'`
- 12,844
- 6
- 48
- 58
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 ;-))
- 37,020
-
1I forgot:
ackis a replacement forgrep -r. See the ack homepage for more info. – topskip Oct 13 '10 at 18:10 -
-
1
findis your friend here. – Juan A. Navarro Oct 13 '10 at 14:50grep -r --include=*.sty "\\everypar" <DIR>(Need to escape the backslash.) – Willie Wong Oct 13 '10 at 15:28texmffolder that should be searched for sty files? Not every distribution sets a value forTEXMFin the login shell. – Sharpie Oct 13 '10 at 18:26