数字のないすべてのディレクトリ(元のパスを除く)を見つけるには、次のコマンドを実行します。
find /path/2/directory -type d -name '[!0-9]*'
問題は、見つかったディレクトリがその番号のディレクトリのサブディレクトリであることです。
例:
/path/2/directory/20160303/backup
でも
/path/2/directory/backup20160303a/backup
findがそのようなディレクトリを返すのを防ぐ方法はありますか?
深さを制限するだけでは、この問題を解決できません。深さはさまざまです。
例:
/path/2/directory/subdirectory/20160303/backup
答え1
-prune
次のディレクトリを無視するために使用されます。
find /path/to/directory -name '*[0-9]*' -prune -o -type d -print
ただしgnu
、これを設定する場合は、上記のC
コマンドを実行するときにロケールを使用することをお勧めします。以下のStéphaneの説明を参照してください。
答え2
find が特定の一致を超えないようにするには、たとえば with の出力をフィルタリングする-prune
代わりに and を使用する必要があります。-path
find
grep -v
find
テスト用に不要な資料が表示されないことを確認できるように、追加のファイルとサブディレクトリを含む環境を作成します。
mkdir -p tmp/2/abc/def
touch tmp/2/abc/def/file1
mkdir -p tmp/2/abc/9876/xyz
touch tmp/2/abc/9876/xyz/file2
tree tmp/
以下を提供します。
tmp
└── 2
└── abc
├── 9876
│ └── xyz
│ └── file2
└── def
└── file1
find tmp/2/abc \! -path "*[0-9]*"
@terdonの提案によれば、以下から始まるディレクトリだけでなくフルパスも考慮されるため、出力は空になり-path
ます。abc
2
@casが提案したようにこれを行うと、find tmp/2/abc -type d | grep -vE '/[0-9-]+(/|$)'
検索しているファイルとのみ一致するのではなく、名前付きディレクトリと一致するため、何も印刷されないことがわかります2
。まず最初にツリー全体を巡回するには find が必要で9876
、そこに数十万の項目がある場合、巡回 (およびフィルタリング) に多くの時間がかかります。
これにより:
find tmp/2/abc -type d -name '[!0-9]*' -print
出力にパスが含まれていることがわかりますtmp/2/abc/9876/xyz
。それを取り除くには、望ましくないものを切り取ります-prune
。
find tmp/2/abc -type d -name '[!0-9]*' -print -o -name '[0-9]*' -prune
これは作る:
tmp/2/abc
tmp/2/abc/def
@don_cristtiがこの回答を向上させるために行ったトリムと印刷を置き換えることで、効率をわずかに向上させることができます。
答え3
私はあなたが探していると思います-path
:
-path pattern
File name matches shell pattern pattern. The metacharacters do
not treat `/' or `.' specially; so, for example,
find . -path "./sr*sc"
will print an entry for a directory called `./src/misc' (if one
exists).
指定されたパターンに対して各ファイル/ディレクトリのフルパスを取得します。したがって、次のディレクトリ構造がある場合:
$ tree
.
├── 111
│ └── foo
│ └── bar
├── bar
│ └── foo
│ └── baz
└── foo
└── 111
└── bar
9 directories, 0 files
次のように使用できますfind
。
$ find /path/to/directory/ \! -path "*[0-9]*"
.
./foo
./bar
./bar/foo
./bar/foo/baz
またはGNUを使用してくださいfind
。
find /path/to/directory/ -not -path "*[0-9]*"
これは、名前を解決するために各ディレクトリをドリルダウンする必要があるため、大きなディレクトリツリーよりも大きなディレクトリツリーではるかに遅いです。@Anthonのソリューションプラムと一緒に。しかし、何千ものディレクトリがなくても大丈夫です。
答え4
grep
(またはまたはなど)を使用して、awk
出力sed
からperl
これらのディレクトリを簡単に削除できます。find
find /path/to/directory -type d | grep -vE '/[0-9-]+(/|$)'
-
注:日付を含むディレクトリは時々YYYYMMDDではなくYYYY-MM-DDであるため、これを文字クラスに含めました。