
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
2
bash
答え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