bash でファイル移動するスクリプトの書き方について教えてください。



以下のような、ディレクトリがあります。

#移動元ディレクトリ
logdir=/export/home/user/t_dir ・・・>*.log(20080801.log、20080802.log、20080801_console.log…)複数ファイルがある
sardir=/export/home/user/t_sar_dir ・・・>sar*(sa20080801、sa20080802…)複数ファイルがある
#移動先ディレクトリ
targetdir=/export/home/user/mv_dir

移動元のディレクトリに、指定のファイル(※1)がある場合、targetdir へ
移動させ、両ディレクトリ内(片方・両方)マッチするファイルがなければ、何もせず終了という処理をしたいのですが、
どのように記述したらよいでしょうか。

(※)logdirには、複数の種別のログファイルがあり、mvコマンドでいうところ「mv 200808*_console.log」
  にマッチするファイルを移動させたい
  sardirも同じ mvコマンドでいう「mv sa200808*」

よろしくおねがいします。

回答の条件
  • 1人10回まで
  • 登録:2008/08/26 23:51:44
  • 終了:2008/08/29 21:18:20

回答(4件)

id:Mook No.1

Mook回答回数1312ベストアンサー獲得回数3912008/08/27 01:44:56

ポイント10pt

ほとんどご自身が書いたそのままだと思いますが、問題にされているのは

対象ファイルがない場合にエラーになる点でしょうか。


であれば、下記のような方法で回避できるかと思います。

#!/bin/sh
logdir=/export/home/user/t_dir
sardir=/export/home/user/t_sar_dir
targetdir=/export/home/user/mv_dir

cdir=`pwd`

cd $logdir
for f in 200808*_console.log; do mv $f $targetdir; done

cd $sardir
for f in sa200808*; do mv $f $targetdir; done

cd $cdir

不明な点があったらコメントで対応しますので、有効にお願いします。

http://homepage.mac.com/sdkfz164/terminal/mv.html

http://linux.ascii24.com/linux/allascii/linuxmag/articles/9910/p...

id:otanako

Mookさん

テストしたのですが、以下エラーが出ました。

テスト:t_dirには対象ファイルがあり、t_sar_dirにはファイルが存在しない状態

「mv: sa200808* を使用できません。」

スクリプトは以下となります。

logdir=/export/home/user/t_dir

sardir=/export/home/user/t_sar_dir

targetdir=/export/home/user/t_mv_dir

cdir=`pwd`

cd $logdir

for f in 200808*_console.log; do mv $f $targetdir; done

cd $sardir

for f in sa200808*; do mv $f $targetdir; done

2008/08/27 19:51:10
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402008/08/27 10:19:33

ポイント40pt
#!/bin/sh
logdir=/export/home/user/t_dir
sardir=/export/home/user/t_sar_dir
targetdir=/export/home/user/mv_dir

log_files=`find $logdir -name '200808*_console.log' -print`
sar_files=`find $sardir -name 'sa200808*' -print`

[ -n "$logfiles" ] && mv $logfiles $targetdir

[ -n "$sar_files" ] && mv $sar_files $targetdir

Manpage of TEST

ファイル数が多くなると一つ一つ移動する方法では遅くなりますね。

id:otanako

b-wind さん

ありがとうございます。

ばっちり実行できました。ファイルが存在しない場合も問題なく終了しました。

なお、以下の命令の解釈を教えていただいてよいでしょうか。

[ -n "$logfiles" ] && mv $logfiles $targetdir

[ -n "$sar_files" ] && mv $sar_files $targetdir


ファイルがない場合をどのように命令していますか?

2008/08/27 20:34:03
id:Mook No.3

Mook回答回数1312ベストアンサー獲得回数3912008/08/27 13:17:02

ポイント30pt

最初の回答は、対象ファイルがない場合にエラーになる場合を避けると

言いながら避けられていなかったようです。


b-wind さんの回答で十分だと思いますが、下記のようでもできるかと思います。

#!/bin/bash

logdir=/export/home/user/t_dir
sardir=/export/home/user/t_sar_dir
targetdir=/export/home/user/mv_dir

ls $logdir/200808*_console.log &>/dev/null
[ $? == 0 ] && mv $logdir/200808*_console.log $targetdir

ls $sardir/sa200808* &>/dev/null
[ $? == 0 ] && mv $sardir/sa200808* $targetdir

$? には直前のコマンドの実行結果(成功は0)が入りますので、ファイルがない場合は

実行されません。

ご参考まで。

id:otanako

Mookさん

ありがとうございます。

上記のように実行しましたが、以下のようなエラーとなりました。

(シェル名はmv_log2.sh)

/export/home/user/t_dir/20080801_console.log /export/home/user/t_dir/20080802_console.log

mv_log2.sh: test: unknown operator ==

また、移動していませんでした。

何がいけないのでしょうか。

2008/08/27 20:44:32
id:Mook No.4

Mook回答回数1312ベストアンサー獲得回数3912008/08/27 23:08:58

ポイント10pt

先にも書きましたが、このような対応はコメントで十分ですので

コメントを有効にしていただけないでしょうか。


ubuntu の bash では上記で動作したのですが、

== オペレータでエラーが出ているようなので、下記のように変更ください。

ls $logdir/200808*_console.log &>/dev/null
[ $? -eq 0 ] && mv $logdir/200808*_console.log $targetdir

ls $sardir/sa200808* &>/dev/null
[ $? -eq 0 ] &&  mv $sardir/sa200808* $targetdir

http://www.atmarkit.co.jp/flinux/rensai/theory08/theory08b.html

id:otanako

Mookさん

失礼しました。コメントを有効としました。

なお、上記の記述で、ばっちり移動できました。

あと、b-windさんに質問していた件回答いただき、ありがとうございました。

2008/08/29 21:14:15
  • id:Mook
    せっかくコメントを有効にしていただいたので、差し出がましいですが b-wind さんの
    回答の補足です。
    http://www.image.esys.tsukuba.ac.jp/range_finder/misc/man-sh にもあるように、
    (1) if [ A ] ; then B ; fi
    (2) [ A ] && B
    (3) [ !A ] || B
    はどれも同等です。

    もうすでに調べたと思いますが、-n は文字列の長さが0ではない場合、つまりファイルが存在する場合、
    条件が真になりますから、その場合のみ mv が実行されます。

    ファイルがない場合なにかしたければ、
    [...] を if 構文にし else 部分でメッセージを出すなりすればよいでしょう。
  • id:b-wind
    > ubuntu の bash では上記で動作したのですが、
    > == オペレータでエラーが出ているようなので、下記のように変更ください。
    [ は test コマンドのハードリンクなんで、基本 SHELL は関係ないはず。(組み込みコマンドになっているやつがあるかもしれないけど)
    で、test コマンドの文字列比較は = のはずですね。
  • id:Mook
    最近シェル系から遠ざかっているので勘が鈍ってますが、
    回答での表記は数値比較にはなりませんか?

    文字列だと [ "$?" = "0" ] のようになった気がしたのですが。

    調べたところ、
    bashで == が = の代わりに使用できるようになったのは、bash Ver. 2.02以降です。

    上記への自己回答ですが、ならない気がしてきました。
  • id:b-wind
    > bashで == が = の代わりに使用できるようになったのは、bash Ver. 2.02以降です。
    bash の組み込みコマンドのほうでは [ も使えるようですね。
    自分が使っているのは /bin/[ の方なので、使い方も若干異なるのでしょう。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません