画像を縦にリンクし、印刷用にリンクされた複数のページを出力するには、bashでループを作成する必要があります。

画像を縦にリンクし、印刷用にリンクされた複数のページを出力するには、bashでループを作成する必要があります。

Ubuntu 18.04を実行しています。.jpg次の形式のストーリーボードイメージでいっぱいのディレクトリがあります。

image-0000.jpg
image-0001.jpg
image-0002.jpg
image-0003.jpg
image-0004.jpg
.
.
image-3898.jpg
image-3899.jpg

13枚の画像を垂直にマージして1ページを構成します。したがって、ループ内で一度に13の数値範囲を使用し、ディレクトリに保存する次のコマンドを使用する必要があるようです"./Merged"

convert -append image-{range of 13}.jpg ./Merged/page_001.jpg

私の実験と思考過程は次の通りである。

次のようにネストされたforループを使用しようとしています。ただし、最初の13個のファイルをインポートしてマージしてフォルダに保存するseq -w方法でスクリプトを繰り返す方法を理解できません。その後、ループを終了し、次の13個のファイルを再インポートする式に進みます。現在のフォルダ内のすべてのファイルが完成するか、300ページが作成されるまでです。(from image-0000 to image-0012)./Merged/(from image-0013 to image-0025).jpg

私のスクリプト

#!/bin/bash

# As 3899 image slices will be converted to 300 pages
# I thought to run for loop 300 times

for ((page=1; page<=300; page++))
do
   # As images are slices of pages.
   for slices in $(seq -w 0 3899)
   do

    # We need to merge 13 times so...
    # Should i use for loop with increment as below?
    # for ((smerge=1; smerge<=13; smerge++))
    # do
    #   convert "SOME LOGIC" ./Merged/page_001.jpg
    # done

    # **OR**
    # somehow take 13 numbers from sequence

        convert image-$slices_{RANGE}.jpg -append ./Merged/page_$page.jpg 
        
   done

done

答え1

そしてzsh

#! /bin/zsh -

typeset -Z3 page
files=(image-<0-3900>.jpg)
for ((page = 1; $#files; page++)) {
  convert $files[1,13] -append ./Merged/page_$page.jpg
  files[1,13]=()
}

3901枚の画像(13×300 + 1)があるため、最後のページには1つの画像しかありません。

次のようにすることができますbash

#! /bin/bash -
shopt -s extglob
shopt -s failglob
set -- image-+([[:digit:]]).jpg
for ((page = 1; $#; page++)) {
  printf -v padded_page %03d "$page"
  convert "${@:1:13}" -append "./Merged/page_$padded_page.jpg"
  (($# > 13)) || break
  shift 13
}

POSIXly では、一致するファイルが存在すると仮定し、ファイル名を厳密に調べません。

#! /bin/sh -
set -- image-*.jpg

# disable split+glob, only retain empty removal on unquoted expansions:
set -o noglob; IFS=

page=1; while [ "$#" -gt 0 ]; do
  padded_page=000$page
  padded_page=${padded_page#"${padded_page%???}"}
  convert $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} \
    -append "./Merged/page_$padded_page.jpg"
  [ "$#" -gt 13 ] || break
  shift 13
  page=$((page + 1))
done

ここのファイル名は非常に単純ですが(空白、特殊文字なし...)このコードでは、任意の文字を処理するために特別な注意を払いました。ただし、convert他のimagemagickユーティリティは-(使用されている場合でも)またはincludeで始まる--ファイル名に問題がある可能性があるため、これらの問題を回避する:には、ファイルパスの前にプレフィックスを付けるのが最善です(例:代わりに使用)。././*.jpg*.jpg

答え2

image-0000.jpgからの連続した範囲にこれらのファイルがあるとしますimage-2999.jpg。これはこれがどのように機能するかを示しています。

#!/bin/bash
for page in {000..001}; do
  echo image-${page}{0..9}.jpg
done

したがって、これをユースケースに入れてください。

#!/bin/bash
for page in {000..001}; do
  convert image-${page}{0..9}.jpg --append ./Merged/page-${page}.jpg
done

{01..02}4にスケーリングする必要01 02はありません。1 2bash

答え3

パラメーターを使用してxargs -nこれを実行し、結果をwhile readループに入れることができます。

page=1
while IFS= read -r row; do
    convert $row -append ./Merged/page_$page.jpg
    page=$((page + 1))
done < <(echo image-{0000..3900}.jpg | xargs -n13)

答え4

皆さん、こんにちは。時間をかけて答えてくれてありがとう。

ドフゴティ、フィリップ・ケンダル、スティーブン・チャジェラス、ロボ

それが私が作ることができ、効果がありました。 しかし、他の解決策も確認してみたいです。たぶんあなたのソリューションは私の基本的なスクリプトよりも速いかもしれません。

メモ:ファイル名にスペースが含まれていると、このスクリプトが失敗する可能性があります。

スクリプトのみ

#!/bin/bash

# NOTE: This Script will/might fail if there are spaces in file names!

mkdir -p Finished;
mkdir -p Merged;

for paGe in $(seq -w 1 300)
do
   ls *.jpg | head -n 13 > filesData.txt;
   paGeData=$(sed ':a;N;$!ba;s/\n/ /g' filesData.txt);
   convert $paGeData -append ./Merged/Page_$paGe.jpg;

   while read -r line
   do
      mv $line ./Finished/
   done < filesData.txt
done

注釈付きスクリプト

#!/bin/bash

# NOTE: This Script will/might fail if there are spaces in file names!
# I random capitalize letters in a variable to make them unique,
# As i can't be sure.

mkdir -p Finished;
mkdir -p Merged;

for paGe in $(seq -w 1 300)
do
   # Selecting only 13 files from the current directory
   ls *.jpg | head -n 13 > filesData.txt;

   # Replace newline (\n) with space and place "file names"
   # in one line and storing "sed" output to a variable.
   # So that we use it with "convert" command.
   paGeData=$(sed ':a;N;$!ba;s/\n/ /g' filesData.txt);

   # Merge different images to one long image
   convert $paGeData -append ./Merged/Page_$paGe.jpg;

   # Move files to different directory,
   # So that we can work with next range/batch of files.
   while read -r line
   do
      mv $line ./Finished/
   done < filesData.txt

done

長い思考プロセス。私がコードをインスタントで書く方法に興味がある人がいる場合。これにはいくつかのバグがあるかもしれません。

#!/bin/bash

mkdir -p Finished;
mkdir -p Merged;

for paGe in $(seq -w 1 300)
do

   # Selecting only 13 files from the current directory
   ls *.jpg | head -n 13 > filesData.txt;

   # Replace newline (\n) with space and
   # place file names in one line for the convert command in while loop
#   sed ':a;N;$!ba;s/\n/ /g' filesData.txt > paGeData.txt;
   # We can remove below loop by storing sed (above) output to a variable
   # and substituting it later in the command.
   paGeData=$(sed ':a;N;$!ba;s/\n/ /g' filesData.txt);

   # Merge different images to one long image
   # "line" is a system variable
#   while read -r line
#   do
#      convert $line -append ./Merged/Page_$paGe.jpg
#   done < paGeData.txt
   convert $paGeData -append ./Merged/Page_$paGe.jpg;

   # Move files to different directory,
   # So that we can work with next range/batch of files.
   while read -r line
   do
      mv $line ./Finished/
   done < filesData.txt

done

関連情報