이미지를 세로로 연결하고 인쇄용으로 연결된 여러 페이지를 출력하려면 bash에서 루프를 만들어야 합니다.

이미지를 세로로 연결하고 인쇄용으로 연결된 여러 페이지를 출력하려면 bash에서 루프를 만들어야 합니다.

우분투 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개의 이미지를 수직으로 병합하여 한 페이지를 구성합니다.따라서 루프에서 한 번에 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)가 있으므로 마지막 페이지에는 이미지가 하나만 있습니다.

다음과 같이 할 수 있습니다 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

관련 정보