質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

4回答

3039閲覧

find 指定したディレクトリ除いて表示

coko1

総合スコア276

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2016/09/27 03:33

編集2016/09/27 05:30

find /aaa/bbb/ccc |grep -v -f test.txt

test.txt 内容↓
45683 2016-01-01 13:30 /aaa/bbb/ccc/ddd/log


19846 2016-01-01 14:30 /aaa/bbb/ccc/ggg/up

上記のコマンドはgrepでパターンファイルを読み込みそこに記述されている絶対パスにマッチするディレクトリを除いて表示させているのですが問題が起こってしまいました。

/aaa/bbb/ccc/ddd/log ← ディレクトリ(消したい)
/aaa/bbb/ccc/ddd/login.txt ← ファイル(消したくない)

/aaa/bbb/ccc/ggg/up ← ディレクトリ
/aaa/bbb/ccc/ggg/upload.txt ← ファイル

パターンファイルに記述しているのは絶対パスなので、本来消したいのはディレクトリのみなのですが、パターンファイルにファイルの方もマッチしてしまい意図しないものまで消してしまうようなのです。
何か解決策はないでしょうか?例えばディレクトリに対してだけマッチしているかを確かめる方法など…

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

こういうスクリプトではどうでしょうか?
手元の環境(CentOS 6.5)では、特に問題なく動きました。

bash

1#!/bin/sh 2 3IFS=" 4" 5for d in `find $path -printf "%M %2n %10s %TY-%Tm-%Td %TH:%TM %p\n"` 6do 7 path=`echo $d | awk '{print $6}'` 8 flag=0 9 if [ -d $path ]; then 10 for f in `cat test.txt` 11 do 12 check=`echo $path | grep $f | wc -l` 13 if [ $check -ne 0 ]; then 14 flag=1 15 fi 16 done 17 fi 18 if [ $flag -eq 0 ]; then 19 echo $d 20 fi 21done

投稿2016/09/27 05:52

編集2016/09/27 07:11
ijufumi

総合スコア276

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coko1

2016/09/27 06:33

/aaa/bbb/ccc/ddd/logの下にも階層はあるのですが、上記のやり方ですと/aaa/bbb/ccc/ddd/logのみ消しているのでダメみたいです。
ijufumi

2016/09/27 07:12 編集

スクリプトを修正しました。 サブディレクトリも除外できるようになっていると思います。
coko1

2016/09/27 08:28

上手くいきませんでした。/aaa/bbb/ccc/ddd/log とパターンファイルに記述されていたらlog以下に何百個ディレクトリが存在しても除外したいのですが、上記を試した結果サブディレクトリをいくつかは除外してくれていたみたいですが、全部除外は出来ていませんでした。
guest

0

-type dとするとディレクトリのみ一致します。

投稿2016/09/27 04:18

moonphase

総合スコア6621

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coko1

2016/09/27 04:48

それだとファイルは表示されなくなってしまいませんか?検索結果にはファイルは必要で除外する対象をディレクトリのみにしたいのですが…
moonphase

2016/09/27 04:59

本来消したいのはディレクトリとの事で、ファイルは対象外と思いましたが、そういうわけではないんですね。 ファイルを消す処理とディレクトリを消す処理に分けてはいかがでしょうか。 どうしても1行で記載したいなら、&&で繋げばいいです。
coko1

2016/09/27 05:07

ファイルを消すという処理は行いません。 パターンファイルの記載に/aaa/bbb/ccc/ddd/logというのがあった場合に /aaa/bbb/ccc/ddd/log /aaa/bbb/ccc/ddd/login.txt 本来は上のみにマッチさせたいのに下もマッチして消えてしまうのが問題なのです。消したいものではない意図しないものが消えてしまうのは論外ですし...
moonphase

2016/09/27 05:10

ディレクトリを表示したくないのであれば -type f でいけますが、そういうことではないのかな?
coko1

2016/09/27 05:21 編集

まずfindで /aaa/bbb/ccc 以下のディレクトリ、ファイル含めて表示させるんです。その際にgrepで除外したいものだけ除いて検索結果を表示させます。 grepで除外を行うためにパターンファイルを用意しているのですが、そこでの記述は絶対パス(除外したいディレクトリ)なのです。 でも同じ階層に log と login.txt が存在するために両方にマッチしてしまうと...
guest

0

ベストアンサー

test.txtの指定時に^$を使えば完全一致にできますよ

^/aaa/bbb/ccc/ddd/log$

投稿2016/09/27 03:39

popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coko1

2016/09/27 04:45

45683 2016-01-01 13:30 /aaa/bbb/ccc/ddd/log のような形で一行ごとに表示される形式なんですけどマッチしますか???
popobot

2016/09/27 04:51

実行するコマンドは以下ではないのでしょうか?? find /aaa/bbb/ccc |grep -v -f test.txt
coko1

2016/09/27 04:55

詳しく言うとシェルを実行する際に /aaa/bbb/ccc なりを引数として渡して$pathという変数に格納してfindしてる形です。 find $path | grep -v -f test.txt が正しいですかね。 私の解釈だとパターンファイルに^$を記述するのかと思ったのですが、もしかして違いましたか?
popobot

2016/09/27 04:58

パターンファイルに記述します。
coko1

2016/09/27 05:02 編集

失礼しました。 フォーマットを指定して表示させていました。 find $path -printf "%M %2n %10s %TY-%Tm-%Td %TH:%TM %p\n" |grep -v -f test.txt
coko1

2016/09/27 04:59

findの結果にサイズやタイムスタンプ等を表示させる必要があったので
popobot

2016/09/27 05:05

うーん。その場合、後方一致になっちゃいますね...残念。 /aaa/bbb/ccc/ddd/log$ ※まぁこれでも結構行けるかもですが、あとは試してみてください。
coko1

2016/09/27 05:10

/aaa/bbb/ccc/ddd/logの中にもまだディレクトリたくさんあるんですよね... なので後方一致だと本当に「/aaa/bbb/ccc/ddd/log」しか消えないので消す意味がなくなってしまうんです。
TaichiYanagiya

2016/09/27 06:49

/aaa/bbb/ccc/ddd/log/ 以下すべて(ファイルもディレクトリも)除外であれば、grep に "-E" を付けて、"/aaa/bbb/ccc/ddd/log(/|$)"
guest

0

文字列だけだと、ファイル、ディレクトリの区別はできないので、
もし「ファイルは拡張子が付いている」というルールが適用できるのでしたら、
以下のコマンドでファイルだけ抽出できるかと思います。

bash

1egpep ".txt|.csv|.sh" test.txt

投稿2016/09/27 03:38

ijufumi

総合スコア276

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問