Perl 在文本文件中的特定行中插入带大括号{}的大写字母
我使用的是一个包含大量条目的.bib文件。不幸的是,标题中的大写字母不在花括号内。我们可以写一个简化的脚本把它们放在大括号里吗。文件的示例是Perl 在文本文件中的特定行中插入带大括号{}的大写字母,perl,unix,scripting,awk,latex,Perl,Unix,Scripting,Awk,Latex,我使用的是一个包含大量条目的.bib文件。不幸的是,标题中的大写字母不在花括号内。我们可以写一个简化的脚本把它们放在大括号里吗。文件的示例是 @article{foo2002, author={Foo, A.}, title = {Eating EGGS Daily}, publisher = {ACM}, year={2010} } @article{bar2002, author={Bar, B.}, title = {Going to School}, publisher = {IEEE
@article{foo2002,
author={Foo, A.},
title = {Eating EGGS Daily},
publisher = {ACM},
year={2010}
}
@article{bar2002,
author={Bar, B.},
title = {Going to School},
publisher = {IEEE},
year={1987}
}
@article{alice2012,
author={Alice, C.},
title = {{A} {G}erman in {UK}},
publisher = {ACM},
year={2012}
}
我想更改标题(仅标题而非其他行),使大写字母位于大括号内,例如前两种情况下的标题应为
title = {{E}ating {EGGS} {D}aily},
title = {{G}oing to {S}chool},
但是,如果它们已经在大括号中,我不想更改其他行。因此,第三种情况应该是这样
title = {{A} {G}erman in {UK}},
我有一个来自collaborator的文件,有3200行。输出应该是
@article{foo2002,
author={Foo, A.},
title = {{E}ating {EGGS} {D}aily},
publisher = {ACM},
year={2010}
}
@INPROCEEDINGS{bar2002,
author={Bar, B.},
title = {{G}oing to {S}chool},
publisher = {IEEE},
year={1987}
}
@article{alice2012,
author={Alice, C.},
title = {{A} {G}erman in {UK}},
publisher = {ACM},
year={2012}
}
while()
{
s/([A-Z]+)/{$1}/g如果(/title={.*},/);
打印
}
或者,如果您是Perl一行程序的粉丝:
perl -e 'while (<>) { s/([A-Z]+)/{$1}/g if (/title = {.*},/); print; }' < data
perl-e'while(){s/([A-Z]+)/{$1}/g if(/title={.*},/);print;}'
编辑:如果某些行已正确支撑(并且没有需要更正的混合行),则以下脚本将避免重新支撑已支撑的行:
while (<>)
{
s/([A-Z]+)/{$1}/g if (/title = {[^{}]*},/);
print;
}
while()
{
s/([A-Z]+)/{$1}/g如果(/title={[^{}]*},/);
打印
}
编辑2:如果有些行的大写字母是正确大括号和未正确大括号,我能想到的最简单的方法是对正则表达式进行两次遍历:一次添加大括号,另一次删除双大括号:
while (<>)
{
s/([A-Z]+)/{$1}/g if (/title = {.*},/);
s/{{([A-Z]+)}}/{$1}/g if (/title = {.*},/);
print;
}
while()
{
s/([A-Z]+)/{$1}/g如果(/title={.*},/);
s/{([A-Z]+)}/{$1}/g如果(/title={.*},/);
打印
}
while()
{
s/([A-Z]+)/{$1}/g如果(/title={.*},/);
打印
}
或者,如果您是Perl一行程序的粉丝:
perl -e 'while (<>) { s/([A-Z]+)/{$1}/g if (/title = {.*},/); print; }' < data
perl-e'while(){s/([A-Z]+)/{$1}/g if(/title={.*},/);print;}'
编辑:如果某些行已正确支撑(并且没有需要更正的混合行),则以下脚本将避免重新支撑已支撑的行:
while (<>)
{
s/([A-Z]+)/{$1}/g if (/title = {[^{}]*},/);
print;
}
while()
{
s/([A-Z]+)/{$1}/g如果(/title={[^{}]*},/);
打印
}
编辑2:如果有些行的大写字母是正确大括号和未正确大括号,我能想到的最简单的方法是对正则表达式进行两次遍历:一次添加大括号,另一次删除双大括号:
while (<>)
{
s/([A-Z]+)/{$1}/g if (/title = {.*},/);
s/{{([A-Z]+)}}/{$1}/g if (/title = {.*},/);
print;
}
while()
{
s/([A-Z]+)/{$1}/g如果(/title={.*},/);
s/{([A-Z]+)}/{$1}/g如果(/title={.*},/);
打印
}
这一行程序应能:
awk -F'\\s*=' '$1=="title"{gsub(/[A-Z]+/,"{&}",$2)}7' file
这一班轮应能:
awk -F'\\s*=' '$1=="title"{gsub(/[A-Z]+/,"{&}",$2)}7' file
通过sed
sed——版本
sed(GNU sed)4.2.2
如果无法获得正确的输出,请尝试以下操作:
sed '/title =/ s/\([A-Z][A-Z]*\)/{\1}/g;s/{{\([A-Z][A-Z]*\)}}/{\1}/g' a.bib
通过sed
sed——版本
sed(GNU sed)4.2.2
如果无法获得正确的输出,请尝试以下操作:
sed '/title =/ s/\([A-Z][A-Z]*\)/{\1}/g;s/{{\([A-Z][A-Z]*\)}}/{\1}/g' a.bib
我在提供的数据上尝试了你的脚本,但它不起作用。它输出的数据未经修改。顺便说一句,我检查过,我的系统上的awk
只是gawk
的别名awk--version
返回与gawk--version
相同的版本字符串。那一个给了我一些奇怪的结果,比如title{E}a{ting}{Oggs}{D}{a{ily},
(注意它也吃了=
符号?)和title{{Going}{to School}}}},
awk
只是gawk
的别名awk--version
返回与gawk--version
相同的版本字符串。那一个给了我一些奇怪的结果,比如title{E}a{ting}{Oggs}{D}{a{ily},
(注意它也吃了=
符号?)和title{{{Going}{to School}}}},
{This{O}ne{M}essed Up}
?大多数情况并非如此,但处理此情况并在{U}p中用大括号括住U会很有用too@lovedynasty:我不知道一个简单的方法(因为我的高级perl regex fu很弱),除了替换然后去掉双括号。我将在上面添加第二个编辑。完全按照我想要的方式工作。但我刚刚意识到我必须摆脱那些有花括号的人。那么,我怎样才能摆脱大括号呢。例如,如果title的title={{G}指向{S}chool},我想保持原样,不想添加额外的空格。@LoveDynary:所以如果我理解正确,有些行已经有了必要的花括号,所以你不想意外地将它们加倍?有没有这样的混合情况需要修复{This{O}ne{M}essed Up}
?大多数情况并非如此,但处理此情况并在{U}p中用大括号括住U会很有用too@lovedynasty:我不知道一个简单的方法(因为我的高级perl regex fu很弱),除了替换然后去掉双括号。我将在上面添加第二个编辑。对于sed 4.2.1,它没有将E表示进食,D表示每日,G表示前往sed 4.2.1,它没有将E表示进食,D表示每日,G表示前往sed 4.2.1