簡體   English   中英

遞歸調用重復的Bash腳本,使其無法訪問資產

[英]Recursive call to a duplicated Bash script, making it unable to access the assets

編輯 :由於新出現的問題稍有不同,因此現在以新內容解決了該帖子。 在這里: 如何有效地並行運行大量文件的XSLT轉換?

我一直在嘗試並行處理一個進程,在花了一些時間之后,我想尋求一些幫助...

基本上,我有很多XML文件可以通過特定的XSLT工作表進行轉換。 但是工作表使用對(非常慢)API的調用來獲取其他數據,並且一次性完成整批XML將花費(非常)長時間。

因此,我將所有文件從原始“輸入”文件夾拆分為包含每個大約5000個XML文件的子文件夾,並在每個子文件夾內也復制了以下Bash腳本:

for f in *.xml
do
  java -jar ../../saxon9he.jar -xsl:../../some-xslt-sheet.xsl -s:$f
done

我從包含“輸入”文件夾,Saxon庫和XSLT工作表的“根”文件夾中為每個文件夾調用每個進程:

find input -type d -exec sh {}/script.sh \;

但是我得到這個錯誤:

Unable to access jarfile ../../saxon9he.jar

我想這是由於當目錄中的腳本被調用時,我正在“ root”文件夾中進行操作。 我可以通過復制每個子文件夾中的所有資產來解決問題(如果我是正確的話),但是我發現該解決方案使我當前的方法變得更加笨拙。

感謝任何可能有主意並使我理解這一點的人!

首先,您確實不希望初始化新的Java VM來運行每個轉換:與運行實際轉換相比,這通常會花費更長的時間。 從角度來看,對於“典型”轉換,您通常會看到Java初始化時間3秒,樣式表編譯時間300ms,轉換時間10ms。 因此,如果您找到一種僅初始化Java並編譯一次樣式表的方式,那么10K文檔的總時間將是2分鍾而不是10小時。

有多種方法可以實現此目的,但它們都涉及使用除Shell腳本之外的其他方法來控制過程。 在我看來,最簡單的方法是通過使用collection()函數訪問目錄中的所有文件,從XSLT本身對其進行控制。 如果您使用的是Saxon-EE,它還有一個額外的好處,那就是可以使用計算機上的所有內核並行處理(解析)文件,這可以使處理速度提高4倍左右。 您只需要在樣式表中添加一個入口點,例如:

<xsl:template name="main">
  <xsl:for-each select="collection('file:///my/dir?select=*.xml;recurse=yes')!saxon:discard-document(.)">
    <xsl:result-document href="....">
      <xsl:apply-templates/>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template>

saxon:discard-document調用是可選的,但由於它使文檔符合垃圾收集的條件,因此,內存不足的可能性較小。

編寫控制循環的另一種方法是使用專用的外殼,例如xmlsh。

以這種方式嘗試輸入每個參數的目錄並在其中調用腳本:

for d in */script.sh
do
  (
    cd "$(basename "$d")"
    sh ./script.sh
  )
done

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM