여러 파일에 대한 Bash 실행 스크립트

여러 파일에 대한 Bash 실행 스크립트

ImageMagick에서 명령을 실행하는 간단한 bash 스크립트가 있습니다. 이미지(INFILE - 일반적으로 .tif)를 가져와서 크기를 조정한 다음 결과를 저장합니다(OUTFILE - 일반적으로 .jpg).

INFILE=/path/'image name.tif'
OUTFILE=/path/'image name.jpg'

echo INFILE="${INFILE}" OUTFILE="${OUTFILE}" 

magick -quiet "${INFILE}" \
  -filter LanczosRadius \
  -distort resize 1600 \
  -quality 92 \
  "${OUTFILE}"

스크립트 이름은 Magick-Resize.sh입니다.

이 스크립트를 사용하여 여러 이미지를 일괄 처리하고 싶습니다. 즉, 여러 INFILES에서 실행하고 싶습니다. 예를 들어. 폴더에 100개의 이미지가 있는 경우 각 이미지가 스크립트에 의해 한 번 처리되어 각 이미지에 대한 고유한 OUTFILE을 생성하기를 원합니다.

저는 배쉬를 처음 접했습니다. 저는 다음과 같은 방법으로 크랙했습니다.

INSCRIPT=/path/Magick-Resize.sh

echo INSCRIPT="${INSCRIPT}"

for INFILE in *.tif; do
    if [[ "$INFILE" = *-tagged.tif ]]; then
        continue # skip output
    fi
    name=$(basename "$INFILE")-tagged.jpg
    echo name="${name}"
    "${INSCRIPT}" "$INFILE" > "${name}"
done

그러나 두 개의 .tif 이미지가 포함된 테스트 폴더에서는 파일 이름이 "*.jpg"인 이미지 하나만 출력됩니다.

누구든지 솔루션을 제공할 수 있나요?

저는 민트 20.3을 사용하고 있습니다.

답변1

스크립트에는 매개변수가 없으며 INFILE 및 OUTFILE 이름이 하드코드되어 있습니다.

zsh여기서는 대신 을 사용 bash하고 다음을 수행합니다.

transform()
  magick -quiet $1 \
   -filter LanczosRadius \
   -distort resize 1600 \
   -quality 92 \
   $2

autoload -Uz zmv
zmv -P transform './(^*-tagged).tif' './$1-tagged.jpg'

답변2

나는 문제를 해결하는 또 다른 방법을 보여주었습니다: bash.

  • 쉘 스크립트 만들기
  • #!/bin/bash스크립트를 실행할 쉘을 제어하려면 맨 위에 shebang을 넣으십시오.
  • "실행자" 부분에 대해 별도의 쉘스크립트 대신 함수를 만듭니다.
  • 내 시스템에서 Image Magick 도구가 구현되는 방식이므로 에서 magick로 전환하세요 . convert시스템에서 다시 실행하도록 쉽게 전환할 수 있습니다.
  • 일괄 처리 섹션을 조정하여 더욱 강력하게 만들었습니다.
    • # comments무슨 일이 일어나고 있는지 이해하는 데 도움이 되는 몇 가지 콘텐츠를 추가하세요 . 태그된 파일이 발견되면 건너뛰고, 그렇지 않으면 태그된 jpg 파일을 생성합니다.
    • 파일 이름에 대한 bash 변수를 조작하고 테스트하여 필요한 파일만 생성합니다. 이에 대해서는 man bash매개변수 확장 장에 설명되어 있습니다.

두 개의 인수를 사용하여 함수를 호출하는 방법 doer과 해당 인수가 함수 내에서 어떻게 처리되는지 확인하세요 $1.$2

#! /bin/bash -

function doer() {
  INFILE="$1"
  OUTFILE="$2"
  #echo INFILE="${INFILE}" OUTFILE="${OUTFILE}" 
  convert -quiet "${INFILE}" \
    -filter LanczosRadius \
    -distort resize 1600 \
    -quality 92 \
    "${OUTFILE}"
}

#######
# main
#######

shopt -s nullglob
files=(./*.tif)
if (( ${#files[@]} )); then
  # there is at least one tif file, so continue
  for INFILE in "${files[@]}"; do
    if [[ "$INFILE" != *-tagged.tif ]]; then
      # not a tagged tif file, so create variable 'name'
      name="${INFILE%.tif}-tagged.jpg"
      if ! test -s "$name"; then
        # not a tagged jpg file, so create file 'name'
        printf '%s\n' "${name}"
        doer "$INFILE" "${name}"
      fi
    fi
  done
else
  echo >&2 "no tif files found"
  exit 1
fi
echo "normal termination"

답변3

나는 이것이 귀하의 요구에 충분하다고 생각합니다.

먼저 다음을 extglob실행하여 활성화하세요.shopt -s extglob

for i in !(*-tagged).tif; do 
    magick "./$i" <flags> "./${i%%.tif}-tagged.jpg"; 
done

이는 GNU Parallel을 통해 간단히 병렬화할 수도 있습니다.

parallel magick ./{} <flags> ./{.}-tagged.jpg ::: !(*-tagged).tif

관련 정보