13

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 Answers4

16

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.

muk.li
  • 3,620
Stefan Kottwitz
  • 231,401
  • 1
    These 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
3

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'`
Sharpie
  • 12,844
  • 6
  • 48
  • 58
2

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 ;-))

topskip
  • 37,020
1

It is slightly easier for ConTeXt. Just enter your search phrase in the search box here

Aditya
  • 62,301