SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

業務でラクするためのUNIXテクニック集

ファイル・ディレクトリ名の一括置換/一括作成
業務で楽するためのUNIXテクニック集

第2回


  • X ポスト
  • このエントリーをはてなブックマークに追加

ファイル名置換に関する便利なUNIXテクニック例

 最後に、コマンドやシェルの制御構造を利用したいくつかの例を紹介しておきます。業務に合わせて応用しながら使ってください。

 また、誤ってファイルを上書きするのを防ぐには、mvコマンド/cpコマンドに「-i」「-b」オプションを付けて実行するか、「ファイルの一括作成」「シンボリックリンクの作成」で紹介したテクニックを利用して事前に検証環境を構築し、動作確認を行ってください。

サブディレクトリに渡るすべてのファイル名だけに拡張子「.bak」を付ける

$ find . -type f -print0 | while read -r -d '' file; do mv "$file" "$file.bak"; done

 xargsコマンドを利用する場合は、次のように指定できます。

$ find . -type f -print0 | xargs -0 -I% mv % %.bak

 findコマンドのアクションを利用する場合は、次のように指定できます。

$ find . -type f -exec mv '{}' '{}.bak' \;

同一階層内のすべてのディレクトリ・ファイル名から拡張子「.bak」を取り除く

$ find * -maxdepth 0 -name "*.bak" -print0 | while read -r -d '' file; do mv "$file" "${file%%.bak}"; done

 シェルの変数展開「${パラメータ%%パターン}」を用いて、拡張子名「.bak」を取り除いています。

 xargsコマンドを利用する場合は、次のように指定できます。

$ find * -maxdepth 0 -name "*.bak" -print0 | perl -pe 's/\.bak\0/\0/g' | xargs -0 -I% mv %.bak %

同一階層の複数のファイル名の拡張子「.text」を「.txt」に置き換える

$ for file in *.text; { mv "$file" "${file%%.text}.txt"; }

 xargsコマンドを利用する場合は、次のように指定できます。

$ find * -maxdepth 0 -print0 | perl -pe 's/\.text\0/\0/g' | xargs -0 -I% mv %.text %.txt

 FedoraやCygwinなどrenameコマンドが使える環境では、より高速にファイル名の置換が可能です(改行文字が含まれるファイル名は置換されません)。

$ rename .text .txt  *.text
※注5

renameコマンドを使うと、「test.text.text」のような二重拡張子を持つファイル名の場合、「test.txt.text」のように最初の拡張子名が置換されてしまいます。

$ ls
test.text.text
$ rename .text .txt  *.text
$ ls
test.txt.text

サブディレクトリに渡るすべてのファイルの拡張子「.text」を「.txt」に置き換える

$ find . -type f -name "*.text" -print0 | while read -r -d '' file; do mv "$file" "${file%%.text}.txt"; done

 シェルの変数展開「${パラメータ%%パターン}」を用いて、拡張子名「.text」を取り除いています。

 xargsコマンドを利用する場合は、次のように指定できます。

$ find . -type f -name "*.text" -print0 | perl -pe 's/\.text\0/\0/g' | xargs -0 -I% mv %.text %.txt

サブディレクトリに渡るすべてのファイルの拡張子を「.txt」に変更する

$ ls
test A.txt  test".txt  test.txt.bak

$ find . -type f -print0 | while read -r -d '' file; do mv "$file" "${file%.*}.txt"; done

$ ls
test A.txt  test".txt  test.text.txt

 シェルの変数展開「${パラメータ%パターン}」を用いて、一度拡張子を取り除いてから、拡張子を付け足しています。「%%」ではなく「%」とすることで、二重拡張子のファイルでも、最後の拡張子のみを置換してくれます。


サブディレクトリに渡る拡張子のないすべてのファイルに「.txt」を付ける

$ find * -type f ! -name "*.*" -print0 | while read -r -d '' file; do mv "$file" "$file.txt"; done

 xargsコマンドを利用する場合は、次のように指定できます。

$ find * -type f ! -name "*.*" -print0 | xargs -0 -I% mv % %.txt

 findコマンドのアクションを利用する場合は、次のように指定できます。

$ find . -type f ! -name "*.*" -exec mv '{}' '{}.bak' \;

サブディレクトリに渡るすべてのディレクトリ・ファイル名に拡張子「.bak」を付ける

$ find * -print0 | sort -rz | while read -r -d '' file; do mv "$file" "$file.bak"; done

 最初にディレクトリ名が置換されると、そのディレクトリ内のファイル名置換が正しく行われません。そのため、ディレクトリ名の置換は最後に行うよう、sortコマンドの「-r」オプションで検索結果を逆順に並べています。

 sortコマンドの「-z」オプションは、「\0」(ヌル文字)を区切り文字とするために付けています。「find -print0」や「xargs -0」などと組み合わせて使う場合に必要なオプションです。

 xargsコマンドを利用する場合は、次のように指定できます。

$ find * -print0 | sort -rz | xargs -0 -I% mv % %.bak

同一階層のすべてのファイル名の先頭に「日付-」を加える

$ ls
test A.txt  test".txt  test.text.bak

$ for file in *; { mv "$file" "$(date +%F)-$file"; }

$ ls
2009-02-09-test A.txt  2009-02-09-test".txt  2009-02-09-test.text.bak

 dateコマンドの「+%F」オプションにより、「yyyy-mm-dd」形式の日時を出力しています。

 xargsコマンドを利用する場合は、次のように指定できます。

$ find * -maxdepth 0 -type f -print0 | xargs -0 -I% mv % "$(date +%F)"-%

 findコマンドのアクションを利用する場合は、次のように指定できます。

$ find * -maxdepth 0 -type f -exec  mv '{}' "$(date +%F)"-'{}' \;

サブディレクトリに渡るすべてのファイル名の拡張子の前に「日付-」を加える

$ ls
test A.txt  test".txt  test.text.bak

$ find . -type f -print0 | while read -r -d '' file; do mv "$file" "${file%.*}-$(date +%F).${file##*.}"; done

$ ls
test A-2009-02-09.txt  test"-2009-02-09.txt  test.text-2009-02-09.bak

 拡張子を取り除いて日付を付加し、最後に拡張子を加えています。ここでは、シェルの変数展開「${パラメータ##パターン}」を用いて、ファイル名の前方から「*.」にマッチする部分を除いています。

 なお、コマンドが長い場合は、次のように改行した指定もできます。

$ find . -type f -print0 | while read -r -d '' file;
> do mv "$file" "${file%.*}-$(date +%F).${file##*.}";
> done

 上記の「>」はコマンドがまだ完結していないときにシェルが表示する2次プロンプトです。

まとめ

 今回は「ファイル・ディレクトリ名の一括置換」や「ファイルやシンボリックリンクの一括作成」に関するテクニックを紹介しました。

 今回紹介した指定方法以外にも、コマンドやシェルの制御構造を利用することで、さまざまな指定ができると思います。ただし、特殊文字や空白が含まれるファイル名でも正しく動作するかを確認して業務で使うようにしてください。

 次回以降も、テーマごとにテクニックや小技を紹介していく予定です。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
業務でラクするためのUNIXテクニック集連載記事一覧

もっと読む

この記事の著者

保田和隆(ヤスダカズタカ)

Yasuda Kazutakaネットワーク関連の組み込みソフトウェア開発者。http://uguisu.skr.jp/Windows/

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2954 2009/06/04 09:52

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング