この記事は何
shellgei160を通じて言語習得 Advent Calendar 2023に参加しています。
書籍「シェル芸ワンライナー160本ノック」の例題をRubyで解いてみて、Rubyの学習に役立てようとするものです。
例題はこちらのリポジトリで公開されているものに限ります。
https://github.com/shellgei/shellgei160
実行環境など
- Docker image: ruby:3.0.2
- 上記リポジトリをクローンした上で、リポジトリのルートディレクトリ直下に
answer-ruby
ディレクトリを作り、その中に解答となるファイルを作成していきます。
今回のテーマ
$ time ls -U | xargs -P2 rename 's/^/0000000/;s/0*([0-9]{7})/$1/'
ファイルのリネーム処理の問題です。左から0詰した7桁数値固定のファイル名にリネームします。
あらかじめ./tmp
ディレクトリ内に0
、1
、...999999
みたいなファイルが作ってあるものとします。
解
リネームまですると面倒ですので、旧・新ファイル名を比較表示するにとどめます。
files = Dir.glob('.tmp/*')
files.each do |before|
# formatを使う方法。sprintfも同じ結果を与えそうだが、Linterはformatを推奨している
after = before.gsub(/\d+/) { |s| format('%07d', s.to_i) }
# File.rename(before, after)を実行しても良いが、面倒なのでbefore/afterを出力するだけにする
puts "#{before} -> #{after}"
end
所感
- gsub(検索パターン) {ブロック} にすると、検索パターンをブロック内の計算結果で置き換え