假设我想要grep
一个 tex 文件中使用的所有包:
$ grep usepackage my.tex
可以,但(据我所知)有一个例外:如果一个包加载了太多选项,文件的作者决定插入换行符,例如
\usepackage[option1,
option2,
option3]{thepackage}
有没有办法告诉 grep 继续解析文件直到到达}
?
理想情况下,我只会获得thepackage
as 输出,以便我可以对其进行迭代,例如:
$ for i in `locate `my grep command`.sty`
do
grep \\\\newcommand{\\\\createstrouble} $i
done
为了快速找到\createstrouble
定义命令的包?
编辑:还有一个复杂因素:我有一个\usepackage
如下命令:
\usepackage[pdftitle={My Title},
pdfauthor={My Author}]{hyperref}
编辑:我明白这种方法不适合我的目的,即找出冲突的软件包。主要是因为通过加载的软件包会\usepackage{something}
拉入更多软件包RequirePackage
,而这些软件包不会出现在雷达上。最好使用日志文件,可能\listfiles
在前言中使用,生成已加载文件的列表,并通过texmf
目录查找不同软件包使用的实际命令名称。
答案1
-P
您可以在常规 grep 中使用(PCRE 模式)和-z
标志的组合进行多行匹配,例如
grep -zP '(?s)\\usepackage.+?}' file
或pcregrep
pcregrep -M '(?s)\\usepackage.+?}' file
该(?s)
修饰符允许.
匹配换行符。
要获取包名称,您可以尝试
grep -zPo '(?s)\\usepackage.*?{\K.+?(?=})' file
或者
pcregrep -Mo '(?s)\\usepackage.*?{\K.+?(?=})' file
在自己的 TeX 手稿上测试简单的 grep 表达式,我得到以下软件包列表:
~$ grep -zPo '(?s)\\usepackage.*?{\K.+?(?=})' myfile.tex
geometry
changepage
inputenc
textcomp,marvosym
fixltx2e
amsmath,amssymb
cite
nameref,hyperref
lineno
microtype
rotating
setspace
caption
lastpage,fancyhdr,graphicx
epstopdf
答案2
编写 TeX 解析器并不简单。因此只能尝试以下解决方案。
使用awk
两次和uniq
awk '/usepackage/,/}$/ {gsub(/\\/,"\n",$0);printf "%s",$0}' my.tex |\
awk -F{ '{gsub(/}/,"",$NF); if ($NF != "") {print $NF}}' |\
sort -u
例子
$ cat foo.tex
\usepackage[pdftitle={My Title},
pdfauthor={My Author}]{hyperref}
\usepackage{ngerman}
\usepackage[scale=0.85]{geometry}
$ awk '/usepackage/,/}$/ {gsub(/\\/,"\n",$0);printf "%s",$0}' foo.tex |\
awk -F{ '{gsub(/}/,"",$NF); if ($NF != "") {print $NF}}' |\
sort -u
geometry
hyperref
ngerman