複数の幅を持つファイルの一括名前変更

複数の幅を持つファイルの一括名前変更

似たようなファイルがあります。

file1.txt
file2.txt
file3.txt
...
file11.txt
file12.txt
...
file100.txt
file101.txt
...

次のように同じ文字列幅を持つように名前を変更したいと思います。

file001.txt
file002.txt
file003.txt
...
file011.txt
file012.txt
...
file100.txt
file101.txt
...

これを達成する簡単なコマンドはありますか?たとえば、Rangerbulkrenameを使用して手動で名前を変更することを避けたいと思います。

答え1

マニュアルページからrename(1)、これを行う例を確認できます。

EXAMPLES
       Given the files foo1, ..., foo9, foo10, ..., foo278, the commands

              rename foo foo00 foo?
              rename foo foo0 foo??

       will turn them into foo001, ..., foo009, foo010, ..., foo278

したがって、あなたの場合、簡単な解決策(最も大きい数字が3桁の場合)は次のようになります。

rename file file00 file?.txt
rename file file0 file??.txt

実際のコマンドを実行する前に、renameフラグを追加してテストし、結果を確認できます。--no-act / -n--verbose / -v

$ rename -nv file file00 file?.txt
`file1.txt' -> `file001.txt'
`file2.txt' -> `file002.txt'
`file3.txt' -> `file003.txt'
$ rename -nv file file0 file??.txt
`file11.txt' -> `file011.txt'
`file12.txt' -> `file012.txt'

より一般的なソリューション(bashバージョン3.0から利用可能):

$ for i in `find ./ -maxdepth 1 -type f -name 'file*.txt'`; \
  do if [[ "$i" =~ file([0-9]*).txt$ ]]; \
    then NUM=$(printf "%03d" "${BASH_REMATCH[1]}"); \
    echo mv --verbose $i $i ./file${NUM}.txt; \
  fi; \
done
mv --verbose ./file1.txt ./file001.txt
mv --verbose ./file2.txt ./file002.txt
mv --verbose ./file3.txt ./file003.txt
mv --verbose ./file11.txt ./file011.txt
mv --verbose ./file12.txt ./file012.txt
mv --verbose ./file100.txt ./file100.txt
mv --verbose ./file101.txt ./file101.txt

echo変更を加えるには削除してください。これは単なる例に過ぎず、ファイルのプレフィックスとサフィックスを行のパターンに変更し、ifそのパターンキャプチャを使用して$BASH_REMATCHより複雑な名前を変更することもできます。たとえば、

$ for i in `find ./ -maxdepth 1 -type f`; \
  do if [[ "$i" =~ ^([^0-9]*)([0-9]*).txt$ ]]; \
    then NUM=$(printf "%03d" "${BASH_REMATCH[2]}"); \
    echo mv --verbose $i ${BASH_REMATCH[1]}${NUM}.txt; \
  fi; \
done
mv --verbose ./file1.txt ./file001.txt
mv --verbose ./file2.txt ./file002.txt
mv --verbose ./file3.txt ./file003.txt
mv --verbose ./file11.txt ./file011.txt
mv --verbose ./file12.txt ./file012.txt
mv --verbose ./file100.txt ./file100.txt
mv --verbose ./file101.txt ./file101.txt
mv --verbose ./something1.txt ./something001.txt
mv --verbose ./another02.txt ./another002.txt

もちろんprintf、コマンドを変更して、ゼロの塗りつぶしの長さを3から別の数字に変更することもできます。

答え2

すべてのASCII 10進数シーケンスを含むファイルの名前を幅3(0を含む)のファイルに変更するには、次のようにしますzsh

autoload -Uz zmv
zmv -n '*' '${f//(#m)<->/${(l[3][0])MATCH}}'

-n結果が満足であれば、削除してテストを実行してみてください。)

Perlベースのrename実装(時々file-renameprenameまたはとも呼ばれるperl-rename)と同じです。

rename -n 's/\d+/sprintf "%03d", $&/ge' ./*[0123456789]*

答え3

またはともrename呼ばれるPerlユーティリティを使用します。機能とコマンドラインオプションが完全に異なり、互換性のないユーティリティと混同しないでください。 Perlの名前変更を使用すると、任意の複雑なPerlコードを使用してファイルの名前を変更できますが、ファイル名に対して単純で類似した操作を実行するために最も一般的に使用されます。file-renameperl-renameprenamerenameutil-linuxseds/search/replace/

rename -n 's/^file(\d+)\.txt$/sprintf "file%03i.txt", $1/e' file*.txt

regex 修飾子は/erename に s/search/replace/ 演算子の代替部分を実行可能な Perl コードとして扱うよう指示します。このsprintf機能は、.txt 拡張子の前の数字をゼロで埋めるために使用されます。

あるいは、任意のファイル名のプレフィックスと拡張子で一般化することもできます。

rename -n 's/\A(.*?)(\d+)(\..*)\z/sprintf "%s%03i%s", $1, $2, $3/esm' *

/s正規表現修飾子は、スクリプトがすべての/mファイル名、改行文字を含むファイル名でも機能することを確認するために使用されます。 \A文字列の先頭にあるアンカーポイントと、文字列の終わりにある\zアンカーポイント。

この-nオプションはテスト的に実行されるため、実際にファイル名を変更せずに実行するアクションのみが表示されます。要件を満たしていることが確認されたら、削除または置換して-n詳細な出力を取得します。-v

関連情報