迭代n個檔案?

迭代n個檔案?

我想做一些相當簡單的事。我想montage在包含數千張圖像的目錄上使用,選項很少,即:

me@home$ montage -size 256x256 DSC01*.JPG.svg output.png

……但這還不夠好,因為它一次只能抓取大約 100 張圖像;既不是

me@home$ montage -size 256x256 *.svg output.png

……它同時抓取所有圖像,因為生成的檔案太大而無法解析。

我什麼想做就是一次迭代 100-200 個檔案。我想這可以使用 for 循環(?)來實現,但我只是對如何做到這一點有點困惑。我想可能有一種聰明的方法可以使用find -execxargs我沒有想到。我正在使用bash,但我zsh偶爾使用。

所以,總而言之,我正在尋找一個襯墊,給定 2600 個圖像文件,調用蒙太奇大約 13 或 26 次(每個 100-200 個文件一次),給定 n 個文件,可以調用 n 次的倍數。

答案1

一種bash方法,使用特殊的數組特徵;zsh經過一些修改可能可以翻譯為:

image_files=(*.svg) # use your own glob expression
n=200               # number of files per command line; adjust to taste
for ((i=0; i < ${#image_files[@]}; i+=n)); do
        montage -size 256x256 "${image_files[@]:i:n}" output-"$i".png
done

答案2

您可以使用 xargs 來實作;不幸的是,不可能將 -I (用於插入命令列中間)和 -L (用於限制對可執行檔的單次呼叫的檔案數量)組合。因此,我創建了這個命令行作為範例(但要注意文件名中的特殊字符,它們不受支援):

 ls . | \
   xargs -n 100 echo | \
   (a=1; 
    while read args; do 
     echo montage -size 256x256 $args output-$a.png;
     a=$((a+1)); 
    done
   )

echo如果你想真正執行該命令,請刪除。

注意事項:

  • 檔案名稱不得包含空格或其他特殊字符
  • 最後一個蒙太奇行中的檔案可能少於 100 個

更新:

這是對應的 for 循環,它(我希望)解決了檔案名稱中空格的問題:

a=0
b=0
lst=
for f in *; do 
  a=$((a+1))
  lst="$lst '$f'"
  if test $a -ge 100; then 
    eval echo montage --args $lst target-$b.png
    b=$((b+1))
    a=0
    lst=
  fi 
done

更新2:一個Python解決方案,應該不受檔案名稱中特殊字元的影響

#!/usr/bin/env python
# iterate.py

"""Usage: 
%prog <number per call> <file pattern> <command prefix> -- <command postfix>
e.g.  %prog 100 "DSC01*.jpg.svg" montage -size 256x256 -- output-%i.png """

import sys,subprocess,glob,os

if len(sys.argv) < 5: 
  print __doc__.replace("%prog", os.path.basename(sys.argv[0]))
  sys.exit(1)

def chunks(l, n): 
  for i in xrange(0, len(l), n): yield l[i:i+n]

num, pattern, args = int(sys.argv[1]), sys.argv[2], sys.argv[3:]
files, idx = glob.glob(pattern), args.index("--")
before, after = args[0:idx], args[idx+1:]

for idx,chunk in enumerate(chunks(files,num)):
  subprocess.call( before + chunk + [s.replace("%i",str(idx)) for s in after] )

答案3

使用 GNU Parallel,您可以執行以下操作:

parallel -N200 montage -size 256x256 {} output{#}.png ::: *.svg

對於帶有特殊字元的檔案來說當然是安全的(正如您通常對 GNU Parallel 所期望的那樣)。

最小化安裝

如果您只需要並行且沒有安裝「make」(可能係統是舊的或Microsoft Windows):

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
mv parallel sem dir-in-your-$PATH/bin/

觀看介紹影片以進行快速介紹: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1http://tinyogg.com/watch/TORaR/http://tinyogg.com/watch/hfxKj/

答案4

這是使用 xargs 的版本,對於任何檔案名稱都是安全的,但需要一個暫存檔案來儲存計數。調整“-n 100”以調整每個蒙太奇的檔案數量。您也可以將“printf”替換為“find -print0”,但請確保它找不到“count.temp”。

echo 1 >count.temp
printf "%s\0" *.svg | xargs -0 -n 100 sh -c '
    a=`cat count.temp`
    montage --blah "$@" output-"$a".png
    let a=a+1
    echo "$a" >count.temp
    '
rm count.temp

相關內容