获取 bash 中特定字符串之间的字符串列表

Get list of strings between certain strings in bash

给定一个文本文件 (.tex),其中可能包含“\cite{alice}”、“\cite{bob}”等形式的字符串,我想写一个 bash 脚本,它将每个此类字符串("alice" 和 "bob")的括号内的内容存储在一个新的文本文件(例如,.txt)中。 在输出文件中,我希望每个这样的内容都有一行,我也想避免重复。

尝试次数:

怎么样:

grep -oP '(?<=\cite{)[^}]+(?=})' sample.tex | sort -u > cites.txt
  • -PGNU grep 将正则表达式解释为与 Perl 兼容的正则表达式(对于 lookbehindlookahead 组)
  • -o"prints only the matched (non-empty) parts of a matching line, with each such part on a separate output line"(参见manual
  • 正则表达式 匹配前面有 \cite{ 的无大括号文本(正向后视(?<=\cite{)) 然后是右花括号 (positive lookafter group (?=})).
  • sort -u 排序并删除重复项

有关先行和后行组的更多详细信息,请参阅 Regular-Expressions.info dedicated page

您可以使用 grep -o 并对其输出进行后处理:

grep -o '\cite{[^{}]*}' file.tex |
sed 's/\cite{\([^{}]*\)}//'

如果在输入行上只能有一个 \cite,那么 sed 脚本就足够了。

sed -n 's/.*\cite{\([^{}]*\)}.*//p' file.tex

(将其重构为每行提取多次出现的脚本绝非不可能;但祝您在六周后理解您的代码。)

像往常一样,添加 sort -u 以删除所有重复项。

这是一个简短的 Awk 尝试:

awk -v RS='\' '/^cite\{/ {
    split([=12=], g, /[{}]/)
    cite[g[2]]++ }
  END { for (cit in cite) print cit }' file.tex

这很方便,不会打印任何重复项,并且可以轻松处理每行的多个引用。