Como posso executar a pesquisa e substituição em um arquivo de texto com base nas condições?

0

Eu tenho um arquivo de texto grande (.bib) com muitas entradas duplas para alguns campos. Essencialmente, o arquivo é um .bib -file (mais informações aqui ) que tem aproximadamente 1000 entradas. O conteúdo é estruturado assim:

@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}
}

Você verá que há apenas Year definido para a primeira fonte. A segunda fonte, no entanto, tem Year e Date definidos.

EDIT: HINDSIGHT É 20/20

Acabei de perceber que sempre preciso do campo Year porque gerencio todo o arquivo por meio de JabRef . E para gerar uma chave de bibtex, o JabRef precisa do Year -field. Quer dizer, eu não encontrei uma opção para gerar a chave bibtex com a ajuda do yyyy -part do Date -field, então vou editar as condições.

Então, existe uma maneira de fazer as seguintes ações:

  • Se houver apenas Date definido para uma entrada de origem, copie os primeiros 4 dígitos (aaaa) para Year .
  • Se houver apenas Year definido, copie os quatro dígitos para Date .
  • Se houver Date e Year definidos, não faça nada.

Agora seguem as condições antigas, quando eu não tinha pensado no funcionamento interno do JabRef de antemão

Condições antigas, ainda relevantes se você quiser preparar o arquivo .bib para uso com o biblatex e tiver uma mistura do campo Date e Year em seu arquivo:

  • Se houver apenas Date definido para uma entrada de origem, não faça nada.
  • Se houver Date e Year definidos, copie o conteúdo dos colchetes de Date nos colchetes de Year . A captura aqui é, Date pode conter mais informações (pelo formato aaaa-mm-dd) do que Year , então é exatamente por isso que estou anotando essas "condições". Independentemente do conteúdo de Year , Date é mais importante. A menos que eu tenha cometido alguns erros durante a digitação de todas as informações, os primeiros 4 dígitos de Date devem ser iguais a Year , claro.
  • Se houver apenas Year definido, o termo Year pode ser simplesmente substituído por Date .

Algumas notas:

  • Se esta informação puder ser de alguma ajuda neste caso: Eu uso o Windows 7 e o Xubuntu 14.04. Eu tenho o Office 2010, se isso pode ser usado aqui ... ou eu poderia usar algum tipo de ferramenta no Xubuntu, eu não sei.

  • Já verifiquei e aparentemente não posso usar o JabRef para isso, é um pouco complicado demais.

por henry 06.09.2014 / 15:08

2 respostas

2

Eu jogaria perl neste problema. O link deve ajudar. Algo como:

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);
}
    
por 06.09.2014 / 17:20
1

NOTA: Esta solução é para o conjunto original de requisitos. Ele precisaria ser atualizado para funcionar com a versão atual. E também, a resposta baseada em perl é muito mais limpa de qualquer maneira :-)

Se você não se importar em criar alguns arquivos temporários, isso pode ser um ponto de partida: Copie isso em um arquivo e defina o sinalizador do executável ( 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/.*{\(.*\)}.*//g")
    YEAR=$(grep "^[[:space:]]*Year" $file | sed "s/.*{\(.*\)}.*//g")

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

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

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

O que o script faz é:

  • Recebe um parâmetro - o nome do arquivo de entrada
  • Divide o arquivo em vários arquivos temporários, cada um deles contendo apenas um único registro
  • itera os arquivos e os processa individualmente de acordo com suas instruções (desde que eu as entenda bem, isto é - veja abaixo)
  • concatena os arquivos processados em out.bib
  • remove os arquivos temporários.

O script não modifica o arquivo de entrada original, por isso deve ser bastante seguro.

Ainda não estou completamente claro sobre seus requisitos, por isso, se você der uma chance e encontrar alguns casos em que ele não faz o que você espera - sinta-se à vontade para me informar e eu tentarei melhorá-lo.

    
por 06.09.2014 / 17:12