他の文字列(ほとんどの場合数行)の前にあり、他の文字列が続く(たとえば、特定の環境に含まれる)特定の文字列を検索するにはどうすればよいですか。
\begin{quote}
%several lines of text
\footnote{%
%probably a few more lines of footnote content
}
%several lines of further text
\end{quote}
\footnote{
だから私は引用符で囲まれた\begin{quote}
脚注end{quote}
(で始まる)を検索しています。実際には、参照された環境内で発生する脚注に含まれる他の環境を検索して2番目の条件レイヤーを追加する必要がありますが、おそらく単純化された例を理解したら、実際の質問を理解することができます。私が検索した実際の環境は、数日.tex
以内に印刷されると予想される約500ページの本のソースコードを構成する約20個のファイルを含むディレクトリで約150回検索されています。インポートすることができ、何度も注意深く見ていないと、目立たなくなります。
*tex
検索結果で一致が発生したファイル名(おそらく検索しますが、複雑すぎる場合はbash forループを使用する可能性があります)とその行番号を取得したいと思います。
人々もこれを覚えておくべきです
\begin{quote}
%something
\end{quote}
%something
\footnote{%
%something
}
%something
\begin{quote}
%something
\end{quote}
何かが何度も起こりますが、これは偽の肯定です。
答え1
これを行うために使用することはできません。またgrep
はなどのより強力な機能が必要です。 Perlでこれを行う非常に簡単な例は次のとおりです。awk
perl
$ cat find-fn-in-quote.pl
#!/usr/bin/perl
while(<>) {
# strip comments so that we ignore commented-out quotes & footnotes.
s/%[^%].*//;
# detect beginning and end of quotes
if (m/\Qbegin{quote}\E/) { $qt = 1; $ql = $.};
if (m/\Qend{quote}\E/) { $qt = 0 };
if (eof) {
# reset line-counter ($.) after every input file
close(ARGV);
# reset $qt to zero, in case of unbalanced begin/end{quote}
$qt = 0;
};
# skip to next input line if we're not inside a quote.
next unless ($qt);
if (m/\\footnote\{/) {
print "$ARGV: found footnote beginning on line $. inside quote beginning on line $ql\n";
# For terse output, comment out or delete the print statement above
# and un-comment one of these:
#printf "%s:fn=%i:q=%i\n", $ARGV, $., $ql;
#printf "%s:%i:%i\n", $ARGV, $., $ql;
};
};
注:このスクリプトはネストを正しく処理しませんbegin{quote}
。人為的な例ではない場合、これが起こる可能性が低いため、これが問題になると疑われます。また、参照がファイル内に完全に存在すると仮定します。実際には、スクリプトは、意図的にend{quote}
これを強制し、1つの入力ファイルのエラー(例:不在)が後続のファイルに影響を与えないようにします。
テスト用に3つのテキストファイルを作成しました。 input1.txt
最初の入力例が含まれています。 input2.txt
2番目の入力例と一致させたくない偽の肯定を含めてください。 input3.txt
input2.txt の後に input1.txt が含まれます (つまりcat input2.txt input1.txt > input3.txt
)。これらの入力ファイルに対してスクリプトを実行すると、次の出力が生成されます。
$ ./find-fn-in-quote.pl *.txt
input1.txt: found footnote beginning on line 3 inside quote beginning on line 1
input3.txt: found footnote beginning on line 14 inside quote beginning on line 12
答え2
awk
バージョン
awk 'FNR==1{looking=0; print FILENAME}
$0~/begin{quote}/{looking=1;next}
$0~/end{quote}/{looking=0;next}
looking&&$0~/footnote{/{print FNR, $0}' *.tex
引用が始まると「表示」を開始し、引用が終わったら「表示」を停止します。
@casの例と同様に、ファイルを開くたびにリセットされます。
脚注で異なる環境を探している場合は、他の動物である他の線}
からバランスを探し始める必要があるため、状況はより厳しくなります。\footnote
答え3
GNU awk:
awk '
/^\\end{quote}$/ && fire {report = report OFS str}
/^\\end{quote}$/ {block=cont=fire=0; str=""}
/^\\begin{quote}$/ {block=1}
block && /^\\footnote{%$/ {cont=1; str=FNR; next}
block && cont && /}/ {fire=1;cont=0}
ENDFILE {if(report)print FILENAME report; report = ""}
' *.tex
出力フォーマット:
filename line_number line_number ...
各ファイルごとに一致する行番号がすべて1行に出力されます。一致しないファイル名は表示されません。