私はManjaro GNU / Linuxを使用しています。このディレクトリの下には、などfiles
の名前を持つサブディレクトリが約650個あります。file1
file2
file3
各サブディレクトリには2〜11個の画像があります.tif
。
以前と同じ名前の同じサブディレクトリにあるすべてのイメージを自動的に.tif
変換.jpeg
または維持するコマンドまたはスクリプトを作成したいと思います。.jpg
私は次のコマンドがあることを知っています。
convert source.tif ~/converted.jpg
助けてもらえますか?
ありがとうございます!
答え1
最も簡単な方法は、ファイル名のサフィックスを使用して見つかった各ファイルを変換するfind
短いインラインスクリプトを実行することです。.tif
find files/ -name '*.tif' -type f -exec sh -c '
for pathname do
convert "$pathname" "${pathname%.tif}.jpg"
done' sh {} +
上記のインラインスクリプトは、sh -c
バッチで見つかった通常のファイルのパス名(サフィックスはディレクトリの下にあります)として呼び出されます。パラメータ置換は値からサフィックスを削除し、最後に追加します。find
.tif
files
${pathname%.tif}.jpg
.tif
$pathname
.jpg
文字列で始まる〜650個のサブディレクトリのみを探し、他のサブディレクトリは無視するのではなくfiles/file*/
検索パスとして使用されます。files/
files
file
これによりファイルは所定の位置に保持されますが、ループ内のコマンドの後にファイルを追加すると、.tif
正常な変換後にファイルを削除できます。&& rm "$pathname"
convert
zsh
シェルでは、find
シェルの高度なファイル名一致と文字列操作機能を放棄して使用できます。
for pathname in files/**/*.tif(D-.); do
convert $pathname $pathname:r.jpg
done
ここではfiles/**/*.tif(D-.)
、名前がディレクトリ内または下で終わるすべての一般的なファイルのリストに展開されます。最後にワイルドカードがある場合、ワイルドカードパターンは通常のファイル(「隠された」名前がある可能性があります)のみに一致します。.tif
files
(D-.)
その後、パス名(ファイル拡張子のない名前)の「ルート」が:r
提供されます$pathname
。
サブディレクトリのファイルfiles/file*/**/*.tif(D-.)
にのみ検索を制限するために使用されます。file*
シェルを使用すると、bash
次のように上記のような操作を実行できます。
shopt -s dotglob failglob globstar
for pathname in files/**/*.tif; do
convert "$pathname" "${pathname%.tif}.jpg"
done
ここで設定されているシェルオプションを使用すると、隠された名前にワイルドカードおよびワイルドカード演算子を使用できます**
。また、zsh
シェルのデフォルト値と同様に、一致しないパターンが原因でエラーが発生します。
答え2
7,000を超えるファイルを使用すると、順番に実行するのに長い時間がかかるため、今日のマルチコアCPUを活用して次のものを使用することをお勧めします。GNUパラレル並列に変換するようにしてください。スピードが速くなるだけでなく、非常に簡単にサフィックスを操作し、進捗レポートを提供し、実際に何もせずに何をするかを確認できるテスト実行を提供します。
次のようになりますbash
。
shopt -s failglob globstar
parallel --dry-run magick {} {.}.jpg ::: files/**/*.tif
出力
magick files/file1/1.tif files/file1/1.jpg
magick files/file2/1.tif files/file2/1.jpg
magick files/file1/2.tif files/file1/2.jpg
magick files/file2/2.tif files/file2/2.jpg
magick files/file3/1.tif files/file3/1.jpg
magick files/file3/2.tif files/file3/2.jpg
正しく表示されたら、削除して--dry-run
実際の操作をやり直してください。
ファイルが多すぎてエラーが発生した場合は、ファイル名をmagick
fromにパイプすることができます。ここに進行状況バーfind
も追加しました。--bar
find files -iname "*.tif" -print0 | parallel -0 --dry-run --bar magick {} {.}.jpg
一部の回答とは異なり、TIFFファイルに大文字のサフィックスがある場合にも機能します。
答え3
cd
サブフォルダーを含むホームディレクトリを入力した後。
IFS=$'\n'
for i in $(find -type f -name "*tiff"); do
echo $i
convert $i $i.jpg
done
find -type f -name "*tiff" -exec rm {} \;
IFS
内部フィールド区切り記号。
私が見た問題の1つは、basename
ファイルの内容を抽出できないことです。
大きなフォルダに移動する前に、まず小さなフォルダで試してみることを忘れないでください。
答え4
次のようなスクリプトを使用します。
#!/bin/bash
if [[ $# -gt 0 ]]
then
if [[ -d $1 ]]
then
cd $1
else
echo "Given path leads to a file or the directory you are loking does not exist!"
exit 1
fi
fi
for dir in */
do
echo "Changing directory to $dir"
cd $dir
for image in *
do
if [[ -f "$image" ]]
then
filename="${image%.*}"
extension="${image##*.}"
if [[ "$extension" =~ ^ti[f]{1,2}$ ]]; then
echo "Converting $image to ${filename}.jpg"
convert "$image" -compress JPEG -quality 50 "${filename}.jpg"
fi
fi
done
cd - > /dev/null
done
スクリプトを設定してください。
- BatchJPEGConvert.shとして保存します。
- コマンドを使用して
chmod 755 batchJPEGConvert.sh
ファイルを実行可能にします。 - 次のコマンドを使用して
sudo cp batchJPEGConvert.sh /usr/local/bin
システムからスクリプトにアクセスできるようにします。
batchJPEGConvert.sh
またはを入力してこのスクリプトを実行できますbatchJPEGConvert.sh path
。最初のオプションは、現在の作業ディレクトリでスクリプトを実行します。別のオプションは、作業ディレクトリを指定のディレクトリに変更しようとします。道そこからスクリプトを実行します。このスクリプトはただ.tiff または .tif 拡張子で終わるファイルを変換します。 JPEG圧縮も適用されます。
このスクリプトは、次のように構成されたディレクトリでのみ機能します。
test
├── 1
│ ├── polski.jpg
│ └── polski.tiff
└── 2
├── polski.jpg
└── polski.tif