- ベストアンサー
シェル ディレクトリ内検索について
お世話になっております。 solarisでシェル作成に辺り教えてください。 あるディレクトリの新しいファイルから3つ目の ファイルを移動(mv)したいと考えているのですが 良い方法は無いでしょうか? 例 testディレクトリ内 ファイル.txt.051025 ファイル.txt.051024 ファイル.txt.051023 ←このファイルをmv処理 ファイル.txt.051022 ファイル.txt.051021 ファイル.txt.051020 ディレクトリ内のタイムスタンプで最も新しいファイルから3つ目を移動させたい場合は、どの様にしたら良いでしょうか?方法はあるのでしょうか? お願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> ora8i:/opt/ora8i/sandaijitest/taihi[17]./test_mv.sh > test03.txt --> /opt/ora8i/sandaijitest/taihi > mv: test03.txt を使用できません。 > ora8i:/opt/ora8i/sandaijitest/taihi[18] これは外部要因ではありません。 /opt/ora8i/sandaijitest/taihi でスクリプトを実行していますので、実際のmvはコマンドラインでいえば ora8i:/opt/ora8i/sandaijitest/taihi[1]mv test03.txt /opt/ora8i/sandaijitest/taihi を実行したことになります。test03.txt の所在は /opt/ora8i/sandaijitest/test1 ですので 「mv: test03.txt を使用できません。」ということになってしまいます。 シェルスクリプトの中でファイル処理を行うときには、ファイル名がフルパスで指定されるように工夫するのが大切です。 この場合は set SRCDIRS = /opt/ora8i/sandaijitest/taihi/test1 set DESTDIRS = /opt/ora8i/sandaijitest/taihi set FILESINDIRES = (`ls -t -1 $SRCDIRS`) echo mv $SRCDIR$FILESINDIRES[3] $DESTDIRS mv $SRCDIR$FILESINDIRES[3] $DESTDIRS みたいに書くと良いのではないでしょうか。 ls の -1 オプションは1 行の出力につき 1 つのエントリを出力するオプションです。echo の部分は実際に実行されているコマンドを表示するようにしてみました。(コピーペーストして、頭にechoを入れただけですけど、動作確認には役に立ちます) また一歩すすんで、対象となるファイルが .txt の拡張子を持つと限定できるのであれば、 set SRCDIRS = /opt/ora8i/sandaijitest/taihi/test1 set DESTDIRS = /opt/ora8i/sandaijitest/taihi set FILESINDIRES = (`ls -t -1 $SRCDIRS/*.txt`) echo mv $FILESINDIRES[3] $DESTDIRS mv $FILESINDIRES[3] $DESTDIRS と書くことができます(この場合のlsの出力はフルパス表記となります) 工夫のしどころはまだあると思いますので、いろいろ試してみてください。
その他の回答 (3)
- monda
- ベストアンサー率87% (50/57)
> ora8i:/opt/ora8i/sandaijitest/taihi[17]./test_mv.sh > test03.txt --> /opt/ora8i/sandaijitest/taihi > mv: test03.txt を使用できません。 > ora8i:/opt/ora8i/sandaijitest/taihi[18] さて、何が原因でしょう。 変数には正しくセットされているようなので、それ以外の外部要因の ように思います。例えば: ・Permission denied ・mvしようとした対象のファイルがロックされている。 など。 まずは、バッチシェルで行おうとしている操作を普通にコマンドラインから 実行できるか確認してみましょう。 ディレクトリ名から想像するに Oracle が吐き出したファイルみたい ですので、ファイルがオープンされっぱなしでクローズされてないとか、 親ディレクトリの書き込み権限がないとか、もしくは同じファイルを samba などから開いたままになっているとか。 --
補足
お世話になっております。 原因はわかりませんね。 ファイルのロックは無いかと思います。 このファイルは、自分で作ったTESTファイルなので oracleは関係して無いと思います。 親ディレクトリの権限も特に気になる点は無いです。 コマンドラインから実行した場合は、 ora8i:/opt/ora8i/sandaijitest/taihi[70]set destdirs = /opt/ora8i/sandaijitest/taihi ora8i:/opt/ora8i/sandaijitest/taihi[71]set FILESINDIRES = (`ls -t /opt/ora8i/sandaijitest/test1`) set: 一致しません。 ora8i:/opt/ora8i/sandaijitest/taihi[72] と出力されます。 環境変数を使わないやり方などありますでしょうか?
- monda
- ベストアンサー率87% (50/57)
> (1)set destdirs = '/tmp'の『’』は必要でしょうか? 無しでも問題ありません。が、変数をセットするときの習慣 として付けておいたほうがよろしいです。 > (2)set filesindires = (`ls -t ./`)この場合は、./の > ディレクトリとなるのでしょうか? > /varにしたい場合は > set filesindires = (`ls -t /var`)とすればよいのでしょうか? そのとおりです。 カレントディレクトリならこんな引数をつける必要など 無いのですが、おかしな値をセットしてしまった時の 被害最小化保険として記述してあります。 質問者さまがご存知かどうか知りませんが、' と ` の違いは重要です。 この場合は ` でなければいけません。 ` で括ると、「` で括られたコマンドの実行結果として標準出力に 入るもの」という意味になります。 > (3)#mv $filesindires[3] /tmpに『#』が付いていますがこれは外さないといけないんでしょうか? > mv $filesindires[3] destdirs > 以上の様な記述でよろしいでしょうか? これまた、そのとおりです。 それから、ひとつ誤記をしてしまいました。 > mv $filesindires[3] destdirs この 'destdirs' は $destdirs と記述しなければいけません。 mv $filesindires[3] $destdirs です。 --
補足
お世話になっております。 上記を踏まえ、実行したところ処理がうまくいきません。以下にシェル内容を記載します。 なぜできないのでしょうか? unalias ls #!/bin/csh #上から3つ目のファイルを移動 unalias ls set DESTDIRS = /opt/ora8i/sandaijitest/taihi set FILESINDIRES = (`ls -t /opt/ora8i/sandaijitest/test1`) echo $FILESINDIRES[3] '-->' $DESTDIRS mv $FILESINDIRES[3] $DESTDIRS exit ora8i:/opt/ora8i/sandaijitest/taihi[17]./test_mv.sh test03.txt --> /opt/ora8i/sandaijitest/taihi mv: test03.txt を使用できません。 ora8i:/opt/ora8i/sandaijitest/taihi[18] ora8i:/opt/ora8i/sandaijitest/test1[23]ls -l 合計 10 -rwxrwxrwx 1 ora8i dba 2 10月 25日 16:26 test01.txt* -rwxrwxrwx 1 ora8i dba 2 10月 25日 16:29 test02.txt* -rwxrwxrwx 1 ora8i dba 2 10月 25日 16:29 test03.txt* -rwxrwxrwx 1 ora8i dba 2 10月 25日 16:29 test04.txt* -rwxrwxrwx 1 ora8i dba 2 10月 25日 16:30 test05.txt* 恐れ入りますが、ご教授願います。
- monda
- ベストアンサー率87% (50/57)
Solaris なら使えるシェルは /bin/csh でしょうか。 ================================================================ #!/bin/csh unalias ls set destdirs = '/tmp' set filesindires = (`ls -t ./`) echo $filesindires[3] '-->' $destdirs #mv $filesindires[3] /tmp exit ================================================================ こんなカンジでいかが? $destdirs は移動先のディレクトリ、 $filesindires は ls を取った対象のファイルリストの配列、 ls を -t オプションで実行しているので、時刻順に並んでいます。 添え字が配列内の順番そのものです。 --
お礼
早急な対応ありがとう御座います。 /bin/cshを使用してます。この文を参考にさせていただきます。本当にありがとう御座いました。
補足
すいません。いくつか質問させてください。 (1)set destdirs = '/tmp'の『’』は必要でしょうか? (2)set filesindires = (`ls -t ./`)この場合は、./の ディレクトリとなるのでしょうか? /varにしたい場合は set filesindires = (`ls -t /var`)とすればよいのでしょうか? (3)#mv $filesindires[3] /tmpに『#』が付いていますがこれは外さないといけないんでしょうか? mv $filesindires[3] destdirs 以上の様な記述でよろしいでしょうか? 素人のような質問ばかりですいません。 宜しくお願い致します。
お礼
お世話になっております。 set SRCDIRS = /opt/ora8i/sandaijitest/test1 set DESTDIRS = /opt/ora8i/sandaijitest/taihi set FILESINDIRES = (`ls -t -1 $SRCDIRS/*.txt`) echo mv $FILESINDIRES[3] $DESTDIRS mv $FILESINDIRES[3] $DESTDIRS で工夫しながらやっていきます。 何とか解決できそうです。 ありがとう御座います。