如何根据条件在文本文件中执行搜索和替换?

如何根据条件在文本文件中执行搜索和替换?

我有一个大型文本文件 (.bib),其中某些字段有很多重复条目。本质上,该文件是一个.bib-file(更多信息这里) 大约有 1000 个条目。内容结构如下:

@Article{Apak_2011_Financialriskmanagement,
Title                    = {Financial risk management in renewable energy sector: Comparative analysis between the European Union and Turkey},
Author                   = {Apak, Sudi and Atay, Erhan and Tuncer, Güngör},
Journal                  = {Procedia - Social and Behavioral Sciences},
Pages                    = {935--945},
Volume                   = {24},
Year                     = {2011},
Doi                      = {10.1016/j.sbspro.2011.09.013},
ISSN                     = {1877-0428},
}

@Incollection{Berger_1992_OutputMeasurementin,
Title                    = {Output Measurement in the Service Sectors},
Author                   = {Berger, Allen N. and Humphrey, David B.},
Crossref                 = {Griliches_1992_OutputMeasurementinb},
Pages                    = {245--300 book},
Year                     = {1992},
Publisher                = {University of Chicago Press},
Date                    = {1992-10-04},
Booktitle                = {Output Measurement in the Service Sectors},
Editor                   = {Griliches, Zvi and Berndt, Ernst R. and Bresnahan, Timothy F. and Manser, Marilyn}
}

@Book{Bogenstahl_2012_ManagementvonNetzwerken,
  Title                    = {Management von Netzwerken},
  Author                   = {Bogenstahl, Christoph},
  Publisher                = {Gabler},
  Date                     = {2012-01-01},
  ISBN                     = {978-3-8349-3572-4},
  Series                   = {Strategisches Kompetenz-Management}
}

您将看到,Year第一个源仅定义了 。然而,第二个源同时定义了YearDate

编辑:事后看来一切都很清楚

我刚刚注意到我总是需要这个Year字段,因为我通过贾布雷夫。而为了生成 bibtex-key,JabRef 需要 -field 。我的意思是,到目前为止,Year我还没有找到借助-fieldyyyy的 -part生成 bibtex-key 的选项,所以我将编辑条件。Date

那么,有没有办法可以执行以下操作:

  • 如果仅为Date源条目定义了,则将前 4 位数字(yyyy)复制到Year
  • 如果只有Year定义,则将四位数字复制到Date
  • 如果DateYear都已定义,则不执行任何操作。

以下是以前的情况,当时我还没有想过 JabRef 的内部运作

旧条件,如果有人想准备 .bib 文件以供 biblatex 使用并且在他的文件中混合了Date和字段,那么仍然相关:Year

  • 如果仅为Date源条目定义,则不执行任何操作。
  • Date如果和都已Year定义,则将 括号中的内容复制Date到 括号中Year。这里的要点是,Date 可能包含比 更多的信息(按照 yyyy-mm-dd 格式)Year,所以这正是我写下这些“条件”的原因。无论 的内容如何YearDate​​ 都更重要。除非我在输入所有信息时犯了一些错误,否则 的前 4 位数字当然Date应该等于。Year
  • 如果只有定义,则可简单地Year将该术语替换为。YearDate

几点说明:

  • 如果这些信息在这种情况下能有所帮助:我使用 Windows 7 和 Xubuntu 14.04。我有 Office 2010,如果可以在这里使用的话……或者我很乐意在 Xubuntu 上使用某种工具,我不知道。

  • 我已经检查过了,显然我不能为此使用 JabRef,它有点太复杂了。

答案1

我会用 perl 来解决这个问题。http://search.cpan.org/~ambs/Text-BibTeX-0.70/lib/Text/BibTeX.pm应该有帮助。例如:

use Text::BibTeX;

$bibfile = new Text::BibTeX::File "foo.bib";
$newfile = new Text::BibTeX::File ">newfoo.bib";

while ($entry = new Text::BibTeX::Entry $bibfile) {
    next unless $entry->parse_ok;

    if ($has_year = $entry->exists ('year')) {
        $year = $entry->get('year');
    }
    if ($has_date = $entry->exists ('date')) {
        $date = $entry->get('date');
    }
    if ($has_year and ! $has_date) {
        $entry->set('date', $year);
    }
    if ($has_date and ! $has_year) {
        $entry->set('year', substr($date, 0, 4));
    }
    $entry->write ($newfile);
}

答案2

笔记:此解决方案适用于原始需求集。需要更新才能与当前版本配合使用。而且,perl基于此的答案无论如何都更简洁 :-)

如果您不介意创建一些临时文件,这可以作为一个起点:将其复制到文件中并设置可执行标志(chmod +x file

#!/bin/bash
INFILE=$1

# split the file first
awk '/^@/{x="tmp__"++i}{print > x;}' $INFILE

# process individual files
for file in tmp__* ; do 
    DATE=$(grep "^[[:space:]]*Date" $file | sed "s/.*{\(.*\)}.*/\1/g")
    YEAR=$(grep "^[[:space:]]*Year" $file | sed "s/.*{\(.*\)}.*/\1/g")

    # Both year and date. Substitute year with date
    if [[ -n "$DATE" && -n "$YEAR" ]] ; then
        sed -i "s/\(^[[:space:]]*Year.*\)${YEAR}\(.*\)/\1${DATE}\2/g" $file
    fi

    # Only year
    if [[ -z "$DATE" && -n "$YEAR" ]] ; then
        sed -i "s/\(^[[:space:]]*\)Year/\1Date/g" $file
    fi
done

# concatenate the files back
cat tmp__* > out.bib
rm -f tmp__*

该脚本的作用是:

  • 接受一个参数 - 输入文件名
  • 将文件拆分为多个临时文件,每个文件仅包含一条记录
  • 遍历文件并根据您的指示单独处理它们(前提是我理解它们很好,即 - 见下文)
  • 将处理后的文件连接到 out.bib 中
  • 删除临时文件。

该脚本不会修改原始输入文件,因此它应该是非常安全的。

我仍然不完全清楚您的要求,因此,如果您尝试一下并发现某些情况没有达到您的预期 - 请随时告诉我,我会尝试改进它。

相关内容