태그 보관물: shell-script

shell-script

Bibtex 파일에서 선택한 항목을 추출하는 스크립트 문장과 마지막 닫힘으로 마지막 문장을 인식하고

각 항목이 일반적인 구조를 갖는 많은 항목이있는 큰 bibtex 파일이 있습니다.

@ARTICLE{AuthorYear,
item = {...},
item = {...},
item = {...},
etc
}

(어떤 경우 ARTICLE에는 다른 단어가있을 수 있습니다 BOOK)

내가하고 싶은 것은 주어진 AuthorYear로 항목을 추출하고 새로운 .bib 파일에 넣는 간단한 스크립트 (바람직하게는 쉘 스크립트)를 작성하는 것입니다.

AuthorYear의 첫 번째 문장과 마지막 닫힘으로 마지막 문장을 인식하고 항목 을 추출하는 데 }사용할 수 있다고 생각할 수 있지만 실제로이 sed작업을 정확히 수행하는 방법을 모르겠습니다. 누군가 내가 어떻게 이것을 달성 할 수 있는지 말해 줄 수 있습니까?

아마 다음과 같아야합니다

sed -n "/AuthorYear/,/\}/p" file.bib

그러나 }항목의 첫 번째 항목이 닫히면 중지 되어 다음과 같이 출력됩니다.

@ARTICLE{AuthorYear,
item = {...},

따라서 }줄에서 유일한 문자 인지 여부를 인식해야 하며이 경우 읽기를 중지하십시오.



답변

다음 Python 스크립트는 원하는 필터링을 수행합니다.

#!/usr/bin/python
import re

# Bibliography entries to retrieve
# Multiple pattern compilation from: http://stackoverflow.com/a/11693340/147021
pattern_strings = ['Author2010', 'Author2012',]
pattern_string = '|'.join(pattern_strings)
patterns = re.compile(pattern_string)


with open('bibliography.bib', 'r') as bib_file:
    keep_printing = False
    for line in bib_file:
        if patterns.findall(line):
            # Beginning of an entry
            keep_printing = True

        if line.strip() == '}':
            if keep_printing:
                print line
                # End of an entry -- should be the one which began earlier
                keep_printing = False

        if keep_printing:
            # The intermediate lines
            print line,

개인적으로 필터링 로직이 복잡해지면 스크립팅 언어로 전환하는 것을 선호합니다. 그것은 아마도 가독성 요소에 적어도 이점이 있습니다.


답변

바퀴를 재창조하는 대신 전투 테스트를 거친 BibTeX 라이브러리가있는 언어를 사용하는 것이 좋습니다. 예를 들어

#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use BibTeX::Parser;

open my $fh, '<', $ARGV[0];
my $parser = BibTeX::Parser->new($fh);
my @authoryear;
while (my $entry = $parser->next) {
    if ($entry->parse_ok) {
        if ($entry->key eq "AuthorYear") {
            push @authoryear, $entry;
        }
    }
    else {
        warn "Error parsing file: " . $entry->error;
    }
}

# I'm not familiar with bibtex files, so this may be insufficient
open my $out, '>', "authoryear.bib";
foreach my $entry (@authoryear) {
    say $out $entry->raw_bibtex;
}

아마도 모듈을 설치해야 할 것입니다 : cpan install BibTeX::Parser


답변

이제 파이썬으로 BibTeX 데이터베이스를 분석 할 수있는 Python bibparsing 모듈도 있습니다. 예를 들어 다음 스크립트를 사용하여 공동 논문의 저자 수를 계산합니다.

#!/usr/bin/python
import sys
import bibtexparser as bp
with open(sys.argv[1]) as bibtex_file:
    bd = bp.load(bibtex_file)
    for art in bd.entries_dict:
    print("*********")
    ae = bd.entries_dict[art]
    print(ae[u'title'])
    auths=ae[u'author'].split(" and ")
    print(len(auths))
    print(auths[0]+" --- "+auths[-1])


답변

또 다른 옵션은 bibtool을 사용하는 것입니다.

예:

bibtool -- select{$key AuthorYear”} input.bib -o output.bib

특정 경우에 대해서는 설명서 를 확인하십시오 .


답변

이것은 각 줄을 읽고 정규식 일치를 사용하여 머리에 필요한 패턴이있는 각 항목을 추출하는 Bash 스크립트입니다. 당신은 그것을 getbibs또는 무언가를 부를 수 있습니다 :

#!/usr/bin/env bash
# usage: ./getbibs pattern input.bib output.bib

while read entry; do
    if [[ $entry =~ ^@.*{$1,$ ]]; then
        printf "%s\n" "$entry" >> "$3"
        while read item; do
            [[ $item =~ ^@.*$ ]] && break
            printf "%s\n" "$item" >> "$3"
        done
    fi
done < "$2"

1989 년의 저자로 모든 항목을 추출하려면 다음을 수행하십시오.

$ chmod +x ./getbibs
$ ./getbibs 1989 file.bib author.bib

아직 테스트하지 않은 문제가있을 수 있지만 작업에는 문제가없는 것 같습니다.


답변

내가 완성하는 방식은 다른 사람들만큼 좋지는 않지만 완벽하게 작동하지만 다음과 같이 작동합니다.

entries=( AuthorYear1 AuthorYear2 )
for entry in "${entries[@]}" do
     sed -n "/"${entry}"/, /^ *\}/p" refs.bib 
done

명령 줄에서 실행하거나 bash 스크립트에 넣을 수 있습니다.


답변