2013-02-27 131 views
9

मैं सैकड़ों ओडीटी फ़ाइलों को पीडीएफ फाइलों में परिवर्तित कर रहा हूं, और दूसरे के बाद एक करने में काफी समय लगता है। मेरे पास एकाधिक कोर के साथ एक सीपीयू है। समानांतर में ऐसा करने के लिए एक स्क्रिप्ट लिखने के लिए बैश या पायथन का उपयोग करना संभव है? क्या कमांड लाइन से libreoffice का उपयोग कर समानांतर करने के लिए कोई तरीका नहीं है (सुनिश्चित नहीं है कि मैं सही शब्द का उपयोग कर रहा हूं) बैच दस्तावेज़ रूपांतरण? मैं निम्न कमांड बुला अजगर/बैश में यह कर रहे हैं:समांतर दस्तावेज़ रूपांतरण ओडीटी> पीडीएफ लिबरियोइस

libreoffice --headless --convert-to pdf *appsmergeme.odt 

या

subprocess.call(str('cd $HOME; libreoffice --headless --convert-to pdf *appsmergeme.odt'), shell=True); 

धन्यवाद!

टिम

+0

क्या आप एकाधिक CPUs पर एकल 'libreoffice' कमांड चलाने या' libreoffice' पर एकाधिक कॉल करने और फ़ाइलों को अलग से कनवर्ट करने का मतलब है? पहले मामले में आप कुछ भी नहीं कर सकते हैं, दूसरे मामले में यह आसान है। – Bakuriu

+2

उहम, मेरा मानना ​​है कि 'libreoffice' आपको एक पीडीएफ कनवर्टर से अधिक बार चलाने के लिए रोकता है। कई प्रक्रियाओं को बनाने की कोशिश करने से केवल एक '.pdf' फ़ाइल उत्पन्न होती है और अन्य प्रक्रियाएं विफल होती हैं। यह '--nolockcheck' विकल्प का उपयोग करते समय भी होता है। तो, मेरा मानना ​​है कि आपके प्रश्न का उत्तर यह है: आप नहीं कर सकते। आपको रूपांतरण के लिए एक अलग कार्यक्रम का उपयोग करना चाहिए। – Bakuriu

+0

मेरा मानना ​​है कि मैंने एक बार पढ़ा है कि libreoffice हमेशा केवल एक प्रक्रिया का उपयोग करता है (लेखक, इंप्रेशन इत्यादि में भी), जो इसे संभवतः असंभव बना देगा। – lolopop

उत्तर

3

आप एक डेमॉन/सेवा के रूप में लिब्रे ऑफिस चला सकते हैं। कृपया निम्न लिंक देखें, शायद यह आपको भी मदद करता है: Daemonize the LibreOffice service

अन्य सकारात्मकता unoconv का उपयोग करना है। "unoconv एक कमांड लाइन उपयोगिता है जो किसी भी फ़ाइल प्रारूप को परिवर्तित कर सकती है जिसे ओपनऑफिस आयात कर सकता है, किसी भी फ़ाइल प्रारूप में जो ओपनऑफिस निर्यात करने में सक्षम है।"

-1

Untested संभावित वैध:

आप// सक्षम हो सकते हैं करने के लिए:

  • कुछ न्यायोचित तरीके से करता है, उदा फूट डालो अप समानांतर बैचों की एक संख्या में फ़ाइलों उन्हें सभी फ़ोल्डर्स में रखकर;
  • प्रत्येक फ़ोल्डर को संभालने के लिए एक अलग स्थानीय उपयोगकर्ता खाता बनाएं;
  • भागो लिब्रे ऑफिस क्रमानुसार प्रत्येक उपयोगकर्ता के रूप में

उदा

for paralleluser in timlev1 timlev2 timlev3 timlev4 ; do 
     su - $paralleluser -c \ 
     "for file in /var/spool/pdfbatches/$paralleluser ; do \ 
      libreoffice --headless --convert-to pdf $file ; done" 
done 

su - का उपयोग कर आप गलती से अपने असली सत्र से किसी भी वातावरण चर लागू नहीं होंगे करके, तो समानांतर प्रक्रियाओं (संसाधनों के लिए प्रतिस्पर्धा को छोड़ कर) एक-दूसरे के साथ हस्तक्षेप नहीं चाहिए।

ध्यान रखें, ये संभावित रूप से I/O- बाध्य कार्य हैं, इसलिए 1 प्रति CPU कोर चलाना संभवतः आपको बहुत तेज़ी से बढ़ाएगा।

+0

ओपन/लिबरियोइसिस ​​समानांतर में soffice.exe चलाने की अनुमति नहीं देता है – luca76

0

यह धागा या उत्तर पुराना है। मैंने libreoffice 4.4 का परीक्षण किया, मैं पुष्टि कर सकता हूं कि मैं एक साथ libreoffice चला सकते हैं। मेरी लिपि देखें।

for odt in test*odt ; do 
 
echo $odt 
 
soffice --headless --convert-to pdf $odt & 
 
ps -ef|grep ffice 
 
done

0

मैं बैच को golang में एक कार्यक्रम में लिखा है दस्तावेज़/xls फ़ाइलों के हजारों परिवर्तित।

  • पहले से ही परिवर्तित पीडीएफ के लिए दस्तावेजों को छोड़ दिया हैं (यदि नहीं, यात्रा() फ़ंक्शन में जांच हालत टिप्पणी)
  • यहाँ कन्वर्ट करने के लिए अपने दस्तावेज़ों के रास्ते पर "रूट" चर मान निर्धारित मैं 4 धागे का उपयोग कर रहा हूं (मेरे पास 4 कोर के साथ इंटेल i3 है)। आप मुख्य() फ़ंक्शन

कभी-कभी ऐसा हो सकता है कि लिबरॉफ़िस कुछ फ़ाइलों को परिवर्तित नहीं करता है, इसलिए आपको इसे खोलना चाहिए और उन्हें मैन्युअल रूप से पीडीएफ में परिवर्तित करना चाहिए। सौभाग्य से, वे बदलने के लिए मेरे 16.000 दस्तावेजों में से केवल 10 थे।

package main 

import (
    "os/exec" 
    "sync" 
    "path/filepath" 
    "os" 
    "fmt" 
    "strings" 
) 

// root dir of your documents to convert 
root := "/.../conversion-from-office/" 

var tasks = make(chan *exec.Cmd, 64) 

func visit(path string, f os.FileInfo, err error) error { 
    if (f.IsDir()) { 
     // fmt.Printf("Entering %s\n", path) 
    } else { 
     ext := filepath.Ext(path) 
     if (strings.ToLower (ext) == "pdf") { 
     } else { 


      outfile := path[0:len(path)-len(ext)] + ".pdf" 

      if _, err := os.Stat(outfile); os.IsNotExist(err) { 

       fmt.Printf("Converting %s\n", path) 

       outdir := filepath.Dir(path) 
       tasks <- exec.Command("soffice", "--headless", "--convert-to", "pdf", path, "--outdir", outdir) 
      } 
     } 
    } 
    return nil 
} 


func main() { 
    // spawn four worker goroutines 
    var wg sync.WaitGroup 

    // the ...; i < 4;... indicates that I'm using 4 threads 
    for i := 0; i < 4; i++ { 
     wg.Add(1) 
     go func() { 
      for cmd := range tasks { 
       cmd.Run() 
      } 
      wg.Done() 
     }() 
    } 


    err := filepath.Walk(root, visit) 
    fmt.Printf("filepath.Walk() returned %v\n", err) 

    close(tasks) 

    // wait for the workers to finish 
    wg.Wait() 
} 
0

हम unoconv के साथ एक समान समस्या थी। unoconv आंतरिक रूप से libreoffice का उपयोग करता है। हमने इसे एक आमंत्रण में अनकॉन्व में एकाधिक फ़ाइलों को भेजकर हल किया। तो, सभी फ़ाइलों पर पुनरावृत्ति करने के बजाय, हम बस फ़ाइलों के सेट को बाल्टी में विभाजित करते हैं, प्रत्येक बाल्टी ओ/पी प्रारूप का प्रतिनिधित्व करती है। फिर हम बाल्टी के रूप में कई कॉल करते हैं।

मुझे पूरा यकीन है कि libreoffice भी एक समान मोड है।

0

के बाद से लेखक पहले से ही एक वैध जवाब के रूप में अजगर की शुरुआत की:

import subprocess 
import os, glob 
from multiprocessing.dummy import Pool # wrapper around the threading module 

def worker(fname, dstdir=os.path.expanduser("~")): 
    subprocess.call(["libreoffice", "--headless", "--convert-to", "pdf", fname], 
        cwd=dstdir) 

pool = Pool() 
pool.map(worker, glob.iglob(
     os.path.join(os.path.expanduser("~"), "*appsmergeme.odt") 
    )) 

multiprocessing.dummy द्वारा एक प्रक्रिया पूल के बजाय एक थ्रेड पूल का उपयोग करना पर्याप्त है क्योंकि असली समानांतरवाद के लिए नई प्रक्रियाओं वैसे भी subprocess.call() द्वारा अंडे कर रहे हैं।

हम कमांड के साथ-साथ वर्तमान कार्यशील निर्देशिका cwd सीधे सेट कर सकते हैं। बस ऐसा करने के लिए प्रत्येक फ़ाइल के लिए shell लोड करने की आवश्यकता नहीं है। इसके अलावा, os.path क्रॉस-प्लेटफ़ॉर्म इंटरऑपरेबिलिटी को सक्षम बनाता है।