【问题标题】:Insert the capital letters with in curly braces {} in a text file in specific lines在特定行中的文本文件中插入带有大括号 {} 的大写字母
【发布时间】:2014-01-02 13:18:46
【问题描述】:

我正在使用一个包含大量条目的.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}
}

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

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

title = {{G}oing to {S}chool},

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

title = {{A} {G}erman in {UK}},

我有一个来自合作者的文件,有 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}
}

【问题讨论】:

    标签: perl unix scripting awk latex


    【解决方案1】:
    while (<>)
    {
        s/([A-Z]+)/{$1}/g if (/title = {.*},/);
        print;
    }
    

    或者,如果您是 Perl 单行代码的粉丝:

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

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

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

    编辑 2:如果您的某些行混合了正确大写和未正确大写的大写字母,我能想到的最简单的方法是通过常规的两次表达式:一个添加大括号,一个删除双括号:

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

    【讨论】:

    • 完全按照我想要的方式工作。但刚刚意识到我必须逃避那些有花括号的人。那么,我怎样才能摆脱花括号。例如。如果 title 有 title = {{G}oing to {S}chool},我想保持原样,不想添加额外的空格。
    • @lovedynasty :所以如果我理解正确的话,有些行已经有了必要的花括号,所以你不想不小心把它们加倍?
    • 有没有像这样需要修复混合物的情况? {This {O}ne is {M}essed Up}?
    • 大多数情况并非如此,但处理这种情况并在 {U}p 中的 U 周围放置大括号会很有用
    • @lovedynasty:我不知道一个简单的方法(因为我的高级 perl regex fu 很弱),除了替换然后去掉双支撑。我将在上面添加第二个编辑。
    【解决方案2】:

    这个单行应该做:

    awk -F'\\s*=' '$1=="title"{gsub(/[A-Z]+/,"{&}",$2)}7' file
    

    【讨论】:

    • 我在提供的数据上尝试了您的脚本,但没有成功。它输出未修改的数据。
    • 我检查过,顺便说一句,我系统上的awk 只是gawk 的别名。 awk --version 返回与 gawk --version 相同的版本字符串。
    • 那个给了我一些奇怪的结果,比如title {{E}a{ting} {EGGS} {D}a{ily}},(注意到它也吃了= 的符号?)和title {{Going} {to} {School}},
    【解决方案3】:

    通过 sed

    sed --version sed (GNU sed) 4.2.2

     sed '/title =/ s/\([A-Z]\+\)/{\1}/g;s/{{\([A-Z]\+\)}}/{\1}/g'  a.bib
    

    如果没有得到正确的输出,试试这个:

     sed '/title =/ s/\([A-Z][A-Z]*\)/{\1}/g;s/{{\([A-Z][A-Z]*\)}}/{\1}/g' a.bib
    

    【讨论】:

    • 不放 Eating 的 E 和 Daily 的 D 和 go for sed 4.2.1 的 G
    猜你喜欢
    • 2021-12-29
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多