電子書籍の厳選無料作品が豊富!

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です。よろしくお願いいたします。

A 回答 (4件)

> -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 が実行されるので,これが長いと最悪です.
    • good
    • 0
この回答へのお礼

! なるほど~。

幸か不幸か、.bashrcの実行による遅延が、当方環境では少なかったようで、思ったほど長くはない処理時間で済みました。

今回のnoocyte様のご教示は、findについての理解のみならず、
理解する手順まで、頂いたようでとても有り難いものでした。

-exec bash(sh) -c '~~' \;

これは、他のコマンドへの転用も効きそうですので、勉強したいと思います。
#2で、教示頂いたものと合わせて勉強、運用に役立たせていただこうと思います。

ありがとうございました。

お礼日時:2007/01/28 16:47

#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/bas …
    • good
    • 0
この回答へのお礼

noocyte様へ、ありがとうポイントを30点付与しようと思いましたが、ダメなようですね^^;。

付与基準は、まずQ&A的に有効であり、突っ込んだ当方の疑問であったfindコマンドexecオプションがアドバンテージであると個人的に決めつけますと、

#3 20P, #2 10P

ということになりました。
#1様もレスを頂きありがとうございました。
おかげで質問の意図をハッキリさせることとなったからです。

お礼日時:2007/01/28 17:10

例えば *.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/man …

この回答への補足

ありがとうございます。

下記のエラーとなるコマンドのように

find /home/user1/text -name '*.txt' -type f -exec mv %p %h/.. \;
find /home/user1/text -name '*.txt' -type f -exec mv {} `dirname {}`/.. \;
※ \,""等でのエスケープしても動作しない。

-execを介してコマンド発行は可能でしょうか?

補足日時:2007/01/28 08:42
    • good
    • 0

cd


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

この回答への補足

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

補足日時:2007/01/28 04:35
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!