• ベストアンサー

find で探したファイルを探した階層の一つ上へ移動したい

findコマンドで、深い階層にあるファイルを一階層上へ移動するfindコマンド記述方法を探しています。 /home/user1/text/2007/01/06/text/aaa.txt を /home/user1/text/2007/01/06/aaa.txt へ移動するのが目的です。 ファイルの格納状況は、 /home/user1/text/[1983-2007]/[01-12]/[01-31]/text/ という構造のディレクトリに*.txtが格納されています。 suse10.0, bashです。よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • noocyte
  • ベストアンサー率58% (171/291)
回答No.3

> -execを介してコマンド発行は可能でしょうか? 結論から言うと,できますが,実行はかなり遅くなります. 今回初めて,find のソースを少し覗いてみました. (詳しく追いかけたわけではありませんが.) どうやら -exec ではシェルを起動している様子なく, 直接コマンドを呼び出しているようです. それを確認するため,シェルコマンドである alias を -exec に指定して find . -exec alias \; とやってみると,予想通り次のようになりました.  find: alias: そのようなファイルやディレクトリはありません  find: alias: そのようなファイルやディレクトリはありません  find: alias: そのようなファイルやディレクトリはありません  (以下略) したがって -exec の引数に,シェルの構文である `…` を書いても実行されるわけがありません. (私も今回初めて知りました.今まで (たまに) 無駄な努力をしてはあきらめていました.(T_T)) どうしても -exec でシェルの機能を使いたければ,次のようにすれば可能です. find /home/user1/text -name '*.txt' -type f -exec bash -c 'mv {} `dirname {}`/..' \; ただしこの方法では,ファイルが1つ見つかるたびに mv だけでなく bash が起動されるので遅くなります.さらに,bash が起動されるたびに ~/.bashrc が実行されるので,これが長いと最悪です.

mooboogie
質問者

お礼

! なるほど~。 幸か不幸か、.bashrcの実行による遅延が、当方環境では少なかったようで、思ったほど長くはない処理時間で済みました。 今回のnoocyte様のご教示は、findについての理解のみならず、 理解する手順まで、頂いたようでとても有り難いものでした。 -exec bash(sh) -c '~~' \; これは、他のコマンドへの転用も効きそうですので、勉強したいと思います。 #2で、教示頂いたものと合わせて勉強、運用に役立たせていただこうと思います。 ありがとうございました。

その他の回答 (3)

  • noocyte
  • ベストアンサー率58% (171/291)
回答No.4

#3 に補足します. > さらに,bash が起動されるたびに ~/.bashrc が実行される bash の代わりに sh (bash へのシンボリックリンク) を使えば, ~/.bashrc は実行されなくなります. bash のマニュアルを読むと,-exec sh -c '…' \; の代わりに -exec bash --norc -c '…' \; でも ~/.bashrc は実行されなく なるはずですが,実際やってみるとなぜか実行されます.(?_?) bash のマニュアル http://www.linux.or.jp/JM/html/GNU_bash/man1/bash.1.html

mooboogie
質問者

お礼

noocyte様へ、ありがとうポイントを30点付与しようと思いましたが、ダメなようですね^^;。 付与基準は、まずQ&A的に有効であり、突っ込んだ当方の疑問であったfindコマンドexecオプションがアドバンテージであると個人的に決めつけますと、 #3 20P, #2 10P ということになりました。 #1様もレスを頂きありがとうございました。 おかげで質問の意図をハッキリさせることとなったからです。

  • noocyte
  • ベストアンサー率58% (171/291)
回答No.2

例えば *.txt ファイルだけを1階層上に移動したいのなら, find /home/user1/text -name '*.txt' -type f -printf "mv %p %h/..\n" > aaa.sh とすれば,aaa.sh に次のようなシェルスクリプトができます. mv /home/user1/text/2007/01/28/text/aaa.txt /home/user1/text/2007/01/28/text/.. mv /home/user1/text/2007/01/28/text/bbb.txt /home/user1/text/2007/01/28/text/.. mv /home/user1/text/2007/01/28/text/ccc.txt /home/user1/text/2007/01/28/text/..      :      :      : この内容でよければ,次のようにしてこのスクリプトを実行すれば OK. bash aaa.sh なお,以上の方法でうまくいくことが確認できれば,上記の2つのコマンドは次の ように1行にまとめられます. find /home/user1/text -name '*.txt' -type f -printf "mv %p %h/..\n" | bash find のマニュアル http://www.linux.or.jp/JM/html/GNU_findutils/man1/find.1.html

mooboogie
質問者

補足

ありがとうございます。 下記のエラーとなるコマンドのように find /home/user1/text -name '*.txt' -type f -exec mv %p %h/.. \; find /home/user1/text -name '*.txt' -type f -exec mv {} `dirname {}`/.. \; ※ \,""等でのエスケープしても動作しない。 -execを介してコマンド発行は可能でしょうか?

  • netgogo
  • ベストアンサー率22% (4/18)
回答No.1

cd mv or cp rm ではなく find なのでしょうか?

mooboogie
質問者

補足

そうですね。 bashスクリプトや、Perlスクリプトでは出来ますが、 findコマンドについて知りたいというのが主旨です。 コマンド一発で可能なら日頃の作業が楽になります。 レス、ありがとうございます。

関連するQ&A