GUIよりも、コマンドの方が使いやすいと発言し始めたら、熟練者レベルという事を認識できる、ユゲタです。
先日、とあるシステムのサーバー内で、不要になったファイルを大量に削除しなければいけない作業があり、
findコマンドで、抽出して、rmコマンドに受け渡す、ワンライナーコマンドを実行したところ、なんかわからないけど、エラーが出たので、調べてみたら、ファイル名に半角スペースが含まれていました。
5秒で終わると思ってた作業が意外と手こずったという事をブログに残しておきたいと思います。
本日のIT謎掛け
「ワンライナー・コマンド」と、かけまして・・・
「水漏れの修理」と、ときます。
そのココロは・・・
パイプを使って、操作します。
半角スペースのファイルを削除するには・・・
コレ自体はそんなに難しいコトではないのですが、半角スペースにバックスラッシュを付ければいいダケのことです。
例えば、"image (1).jpg"というような、macで同名ファイルがあったばあいに、自動採番されるファイルなど、半角スペースが入っているものを、コマンドでrm削除したい場合は、以下のようにします。
# 普通にエスケープ処理をせずに、実行すると、こんなエラー
$ rm image (1).jpg
bash: 予期しないトークン `(' 周辺に構文エラーがあります
# 半角スペースにバックスラッシュでエスケープしてみる。
$ rm image\ (1).rm
bash: 予期しないトークン `(' 周辺に構文エラーがあります
# 必要な文字列にすべてバックスラッシュを付けてあげる
$ rm image\ \(1\).jpg
また、もう一つの方法として、ファイルをクォーテーションでくくってあげるという手段
$ rm 'image (1).jpg'
$ rm "image (1).jpg"
シングルクォート、ダブルクォートのどちらでも問題なく削除できます。
find連動での問題について
1ファイルずつrmしていく場合は、全くもって問題ないんですが、削除するファイルが多い場合に、パイプで受け渡す場合に、色々とめんどくさい手続きが必要になります。
まずは、エラーの状態を書くk人してみましょう。
# ls検索パターン
ls *.jpg| rm
rm: オペランドがありません
Try 'rm --help' for more information.
# find検索パターン
find . -name "*.jpg" | xargs rm
rm: './image' を削除できません: そのようなファイルやディレクトリはありません
rm: '(1).jpg' を削除できません: そのようなファイルやディレクトリはありません
めんどくさいですねえ、lsやfindの結果は、クォートや、バックスラッシュ対応してくれないんですね。
ワンライナーでの解決方法
これらのエラーを防ぐ方法はいくつかあるので、2つほどご紹介したいと思います。
まず、findコマンドの場合には、-execオプションを使うと、削除をしてくれる機能があります。
$ find . -name "*.jpg" -exec rm {} \;
次に、sedを使って、強制的にエスケープ処理を実行する方法です。
$ ls *.jpg | sed 's/ /\\ /g' | xargs rm
どちらを使ってもいいのですが、間違っても、必要なファイルまで消してしまわないようにしなければいけませんね。
rmコマンドは、取り消しができないですからね!
ミス防止のプチテクニックとしては、"trush"フォルダを作って、その中に削除するファイル一覧を移動(mv)させて、問題がなければ、trashフォルダごと削除(rm)するというやり方をおすすめします。
ディスクからの容量削減をしたい場合は、別サーバーにrsyncやsshで、移動させるという手もあるし、usbスティックモジュールを使ってバックアップを取るというのも悪く有りません。
めんどくさいと考えてしまいがちですが、ひと手間のリスクヘッジができるかどうかが、上級者と初心者の違いですからね。
0 件のコメント:
コメントを投稿