シェルスクリプトのパターンマッチング例外

シェルスクリプトのパターンマッチング例外

したがって、特定のテレビシリーズのエピソード名をまとめて変更する次のシェルスクリプトがあります。

#!/bin/bash
#script for renaming files of form "*01*.ext" to "Episode 01.ext";
counter=0
for all_files in * ; do
  counter=$(( $counter+1  )) #increments $counter by 1;
  #creates counter "number" with two digit format (eg: 01):
  if [[ 1 = $(( $counter<10 )) ]] ; then
    number=0$counter
  else
    number=$counter
  fi
  #checks all file names for presence of $number and renames those files:
  for numbered_file in *$number* ; do 
    ext=${numbered_file##*.}
    mv "$numbered_file" "Episode $number.$ext"
  done
done

今、いくつかの非常に一般的な例外を解決するためにスクリプトを改善したいと思います。特に、「720p」の「20」が「エピソード20」を指していると解釈されることは望ましくありません。だから私が望むのは、*$number*forループ内でパターンをトリミングする方法です。 (変数などに割り当てられているnumber010203

次のことを達成するにはどうすればよいですか?

*ここには「7」はありません。ここには$number「0」や「p」はありません。*

上記のスクリプトでぎこちなく実行される他の事項を自由に指摘してください。これは漠然と役に立つスクリプトに対する私の最初の試みなので、おそらく文体的なモンスターでいっぱいです。 ;-)

答え1

たとえば、既存のツールを再作成したいと思いますmmvrenameこのツールと呼ばれるプログラムはいくつかありますが、rename私が検討しているプログラムはperl renameの別名ですprename(これはperlDebianと派生製品のパッケージに含まれており、おそらく他のパッケージにも含まれます)。ディストリビューション)。

私はその使用法のいくつかの例を提供しましたが、ソースファイル名の例は提供していません(上記の説明を参照)。


しかし、スクリプトはshではなくbashなので、if / then / elseをprintfbashに埋め込まれたゼロパディング$ numberに次のように置き換えることができます。

printf -v number "%02d" "$counter"

POSIXシェルではnumber=$(printf "%02d" $counter)代わりに使用できます。このprintfコマンドはGNU Coreutilsの一部です。

答え2

Bashには正規表現一致構文があります。

[[ $string =~ regexp ]]

しかし、これはあなたがしたいことにあまり役に立ちません。ファイル名から興味深い数字を抽出するには、退屈な部分を削除し、退屈でない数字の最後のシーケンスを維持します。

shopt -s extglob
number=$filename
number=${number//[0-9][0-9]+([0-9])p}
number=${number%%+([^0-9])}
number=${number##*[^0-9]}

関連情報