बाइबेट फ़ाइल से चयनित प्रविष्टियों को निकालने के लिए स्क्रिप्ट


11

मेरे पास कई प्रविष्टियों के साथ एक बड़ी bibtex फ़ाइल है जहां प्रत्येक प्रविष्टि में सामान्य संरचना है

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

(कुछ मामलों में ARTICLEएक अलग शब्द हो सकता है जैसे BOOK)

मैं जो करना चाहूंगा, उसे दिए गए ऑथर के साथ प्रविष्टियां निकालने के लिए एक सरल स्क्रिप्ट (अधिमानतः सिर्फ एक शेल स्क्रिप्ट) लिखी जाएगी और उन लोगों को एक नई .bib फ़ाइल में डाल दिया जाएगा।

मैं कल्पना कर सकता हूं कि मैं ऑथराइर द्वारा प्रविष्टि के पहले वाक्य को और अंतिम को सिंगल क्लोजिंग द्वारा पहचान सकता हूं }और शायद sedप्रविष्टि को निकालने के लिए उपयोग कर सकता हूं, लेकिन मुझे वास्तव में नहीं पता कि यह कैसे करना है। क्या कोई मुझे बता सकता है कि मैं इसे कैसे हासिल करूंगा?

यह शायद कुछ ऐसा होना चाहिए

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

लेकिन }प्रविष्टि के पहले आइटम में बंद होने के कारण यह बंद हो जाता है, इस प्रकार यह आउटपुट देता है:

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

इसलिए मुझे यह पहचानने की जरूरत है कि क्या }एक पंक्ति में एकमात्र चरित्र है और केवल जब मामला होता है तो 'सेड' पढ़ना बंद कर देते हैं।


मैं केवल आपके कोड को थोड़ा संशोधित कर सकता था sed -n "/AuthorYear/,/\}$/p":। $प्रतीक पर ध्यान दें । यह ठीक काम करता है, सिवाय इसके कि यह }एक बीबिटेम के समापन को प्रिंट नहीं करता है । Btw, sedआवश्यक का उपयोग है?
बरुन

@ बरुन का उपयोग sedबिल्कुल भी आवश्यक नहीं है, मैंने सोचा कि यह सबसे आसान विकल्प होगा। मुझे कुछ अलग कोड का पता चला है: sed -n "/AuthorYear/, /^ *\}/p"जो मैं चाहता हूं, ठीक उसी तरह से करना चाहता हूं जिसमें }रिक्त स्थान को बंद करना और सही करना शामिल है यदि कोई हो
मिचेल

जवाबों:


2

निम्नलिखित पायथन लिपि वांछित छानने का काम करती है।

#!/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,

निजी तौर पर, मैं एक स्क्रिप्टिंग भाषा में जाना पसंद करता हूं जब फ़िल्टरिंग तर्क जटिल हो जाता है। शायद, कम से कम पठनीयता कारक पर एक फायदा है।


सावधान, नेस्टेड {}एस के साथ बहुत सारी प्रविष्टियां हैं । यदि आप के साथ समाप्त होता है प्रवेश सुनिश्चित कर सकते हैं \n}, आप के साथ बंद कर सकते हैं^}
vonbrand

8

मैं उस पहिये पर लगाम लगाने के बजाय युद्ध-परीक्षण वाली 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


1

अब हमारे पास पायथन बाइबपर्सिंग मॉड्यूल भी है, जो पायथन के साथ बिबटेक डेटाबेस का विश्लेषण करने की अनुमति देता है। उदाहरण के लिए मैं सहयोगी पत्रों में लेखकों की संख्या की गणना करने के लिए निम्नलिखित स्क्रिप्ट का उपयोग करता हूं:

#!/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])

1

एक अन्य विकल्प बिबटूल का उपयोग करना होगा।

उदाहरण:

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

विशिष्ट मामलों के लिए मैनुअल देखें ।


0

यह एक बैश स्क्रिप्ट है जो प्रत्येक पंक्ति को पढ़ता है और प्रत्येक प्रविष्टि को निकालने के लिए रेगेक्स मिलान का उपयोग करता है जिसके सिर में आवश्यक पैटर्न होता है। आप इसे 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

इसके कुछ मुद्दे हो सकते हैं जिनका मैंने अभी तक परीक्षण नहीं किया है, लेकिन यह कार्य के लिए ठीक काम करता है।


0

बस पूरा होने के लिए, जिस तरह से मैंने खुद को पता लगाया, दूसरों के रूप में उतना अच्छा नहीं था, लेकिन यह काम करता है:

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

इसे कमांडलाइन से चलाया जा सकता है या बैश स्क्रिप्ट में रखा जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.