একটি বাইবেটেক্স ফাইল থেকে নির্বাচিত এন্ট্রিগুলি বের করার জন্য স্ক্রিপ্ট


11

আমার অনেকগুলি এন্ট্রি সহ একটি বিবিটেক্স ফাইল রয়েছে যেখানে প্রতিটি এন্ট্রির সাধারণ কাঠামো থাকে

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

(কিছু ক্ষেত্রে ARTICLEযেমন আলাদা শব্দ হতে পারে যেমন BOOK)

আমি যা করতে চাই তা হল একটি সরল স্ক্রিপ্ট লিখুন (সাধারণত কেবলমাত্র একটি শেল স্ক্রিপ্ট) প্রদত্ত অথেরাইয়ারের সাথে এন্ট্রিগুলি বের করতে এবং সেগুলি একটি নতুন .bib ফাইলে রেখে দেওয়া।

আমি কল্পনা করতে পারি যে আমি লেখক ইয়ারের একটি এন্ট্রির প্রথম বাক্যটি এবং শেষ এককটি একক সমাপ্তি দ্বারা সনাক্ত করতে পারি }এবং সম্ভবত sedএন্ট্রিটি বের করার জন্য ব্যবহার করতে পারি তবে ঠিক কীভাবে এটি করা যায় তা আমি জানি না। কেউ আমাকে বলতে পারেন যে আমি কীভাবে এটি অর্জন করব?

এটি সম্ভবত কিছু হতে হবে

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

তবে }এন্ট্রিটির প্রথম আইটেমটি বন্ধ হওয়ার কারণে এটি বন্ধ হয়ে যায় এইভাবে এই আউটপুটটি দেয়:

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

সুতরাং আমি সনাক্ত করতে হবে যে }এটি একটি লাইনের একমাত্র চরিত্র এবং কেবল যখন 'কেস' পড়া বন্ধ করা উচিত যখন এটি হয়।


আমি শুধুমাত্র আপনার কোড একটু সংশোধন পারে: sed -n "/AuthorYear/,/\}$/p"$প্রতীকটি নোট করুন । এটি সূক্ষ্মভাবে কাজ করে, এটি কোনও }বিবিটেমের সমাপ্তি মুদ্রণ করে না । বিটিডব্লিউ, 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}, তবে আপনি বন্ধ করতে পারবেন^}
ভনব্র্যান্ড

8

আমি সেই চক্রটি পুনরায় উদ্ভাবনের পরিবর্তে যুদ্ধ-পরীক্ষিত বিবিটেক্স লাইব্রেরির সাথে একটি ভাষা ব্যবহার করার পরামর্শ দেব। উদাহরণ স্বরূপ

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


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

এটি কমান্ডলাইন থেকে চালানো যেতে পারে বা ব্যাশ স্ক্রিপ্টে রাখা যেতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.