この記事は何
shellgei160を通じて言語習得 Advent Calendar 2023に参加しています。
書籍「シェル芸ワンライナー160本ノック」の例題をRubyで解いてみて、Rubyの学習に役立てようとするものです。
例題はこちらのリポジトリで公開されているものに限ります。
https://github.com/shellgei/shellgei160
実行環境など
- Docker image: ruby:3.0.2
- 上記リポジトリをクローンした上で、リポジトリのルートディレクトリ直下に
answer-ruby
ディレクトリを作り、その中に解答となるファイルを作成していきます。
今回のテーマ
$ time ls *.png | sed 's/\.png$//' | xargs -P2 -I@ convert @.png @.jpg
ちなみに、これは次のような処理を行っています(by ChatGPT)
このコマンドは、画像変換のための一連の処理を行います。具体的には、以下のステップがあります:
ls *.png
: カレントディレクトリ内のすべての.png
ファイルをリストします。sed 's/\.png$//'
: 各.png
ファイルの拡張子.png
を取り除きます。これにより、ファイル名の拡張子が.png
から.jpg
に変更されます。xargs -P2 -I@ convert @.png @.jpg
:xargs
を使用して、convert
コマンドによる画像変換を実行します。-P2
オプションは、同時に最大2つのプロセスを起動することを指定しています。-I@
オプションは、xargs
が置換文字@
を使用して引数を渡すことを指定しています。各.png
ファイルに対して、convert
コマンドで画像を変換し、.jpg
ファイルに保存します。
簡潔に言えば、このコマンドはカレントディレクトリ内の全ての.png
ファイルを.jpg
ファイルに変換します。同時に最大2つのプロセスを使用して変換を行います。
上記相当の処理をRubyで考えてみます。なお、画像変換の部分は行わず、ファイル名を変更するだけにします。
解
# ここが一番意外なんだけど、このパスはファイル保存場所からの相対パスではなく、
# 実行場所からの相対パスになる
target_dir = './qdata/2/img'
def png2jpeg(filepath)
# ここに変換処理を書く
# mini_magickを使うと簡単にできるらしいが、今回はパス!
# とりあえず、ファイル名を変更するだけにする
# basenameの第2引数に拡張子を指定すると、拡張子を除いたファイル名を取得できる
# 指定しない時は拡張子を含むファイル名が返る
puts "#{File.basename(filepath, '.*')}.jpg"
end
files = Dir.glob("#{target_dir}/*.png")
files.map { |file| png2jpeg(file) }
所感
- File.basename、Dir.globの使い方、なるほど。