将大写字母用大括号{}插入特定行的文本文件中

dis*_*lus 1 unix scripting perl awk latex

我正在使用具有大量条目的a.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},
year={1987}
}

@article{alice2012,
author={Alice, C.},
title = {{A} {G}erman in {UK}},
publisher = {ACM},
year={2012}
}
Run Code Online (Sandbox Code Playgroud)

我想更改标题(只有标题而不是其他行),大写字母在大括号内,例如前两种情况下的标题应该是

title = {{E}ating {EGGS} {D}aily},

title = {{G}oing to {S}chool},
Run Code Online (Sandbox Code Playgroud)

但是,如果它们已经在花括号中,我不想更改其他行.所以,第三种情况应该是这样的

title = {{A} {G}erman in {UK}},
Run Code Online (Sandbox Code Playgroud)

我有一个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}
}
Run Code Online (Sandbox Code Playgroud)

Joe*_*e Z 5

while (<>)
{
    s/([A-Z]+)/{$1}/g if (/title = {.*},/);
    print;
}
Run Code Online (Sandbox Code Playgroud)

或者如果你是Perl one-liners的粉丝:

perl -e 'while (<>) { s/([A-Z]+)/{$1}/g if (/title = {.*},/); print; }' < data
Run Code Online (Sandbox Code Playgroud)

编辑:如果您有一些已经正确支撑的线(并且没有需要更正的混合线),以下脚本将避免重新支撑已经支撑的线:

while (<>)
{
    s/([A-Z]+)/{$1}/g if (/title = {[^{}]*},/);
    print;
}
Run Code Online (Sandbox Code Playgroud)

编辑2:如果你有一些线条混合了正确支撑和不正确支撑的大写字母,我能想到的最简单的方法是通过正则表达式进行两次传递:一次用于添加大括号,一次用于删除双括号:

while (<>)
{
    s/([A-Z]+)/{$1}/g if (/title = {.*},/);
    s/{{([A-Z]+)}}/{$1}/g if (/title = {.*},/);
    print;
}
Run Code Online (Sandbox Code Playgroud)