複数ファイルの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}"

スクリプト名はMagic-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

ただし、2 つの .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パラメータ拡張の章で説明されています。

2つの引数を使用して関数を呼び出す方法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

関連情報