获取 bash 中特定字符串之间的字符串列表
Get list of strings between certain strings in bash
给定一个文本文件 (.tex),其中可能包含“\cite{alice}”、“\cite{bob}”等形式的字符串,我想写一个 bash 脚本,它将每个此类字符串("alice" 和 "bob")的括号内的内容存储在一个新的文本文件(例如,.txt)中。
在输出文件中,我希望每个这样的内容都有一行,我也想避免重复。
尝试次数:
- 我考虑过将 grep 和 cut 结合起来。
从我在 Stack Exchange 上看到的其他问题和答案来看,我认为(模数阅读更多)我可以设法每行至少获得一个这样的内容,但我不知道如何获得所有出现的内容单行,如果其中有几个这样的字符串,我没有看到任何问题或答案给出这方面的提示。
- 我也尝试过使用 sed。昨天我读了 this guide 看看我是否遗漏了一些基本的 sed 命令,但我没有看到任何直接的方法来做我想做的事(指南确实提到 sed 是图灵完备的,所以我确信有一个仅使用 sed 来执行此操作的方法,但我不知道如何操作)。
怎么样:
grep -oP '(?<=\cite{)[^}]+(?=})' sample.tex | sort -u > cites.txt
-P
与 GNU grep
将正则表达式解释为与 Perl 兼容的正则表达式(对于 lookbehind 和 lookahead 组)
-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
这很方便,不会打印任何重复项,并且可以轻松处理每行的多个引用。
给定一个文本文件 (.tex),其中可能包含“\cite{alice}”、“\cite{bob}”等形式的字符串,我想写一个 bash 脚本,它将每个此类字符串("alice" 和 "bob")的括号内的内容存储在一个新的文本文件(例如,.txt)中。 在输出文件中,我希望每个这样的内容都有一行,我也想避免重复。
尝试次数:
- 我考虑过将 grep 和 cut 结合起来。 从我在 Stack Exchange 上看到的其他问题和答案来看,我认为(模数阅读更多)我可以设法每行至少获得一个这样的内容,但我不知道如何获得所有出现的内容单行,如果其中有几个这样的字符串,我没有看到任何问题或答案给出这方面的提示。
- 我也尝试过使用 sed。昨天我读了 this guide 看看我是否遗漏了一些基本的 sed 命令,但我没有看到任何直接的方法来做我想做的事(指南确实提到 sed 是图灵完备的,所以我确信有一个仅使用 sed 来执行此操作的方法,但我不知道如何操作)。
怎么样:
grep -oP '(?<=\cite{)[^}]+(?=})' sample.tex | sort -u > cites.txt
-P
与 GNUgrep
将正则表达式解释为与 Perl 兼容的正则表达式(对于 lookbehind 和 lookahead 组)-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
这很方便,不会打印任何重复项,并且可以轻松处理每行的多个引用。