web-dev-qa-db-ja.com

一致するディレクトリから1レベル下のディレクトリのリストを見つける

特定のフォルダに含まれるディレクトリのリストを取得しようとしています。

これらのサンプルフォルダーがあるとします。

foo/bar/test
foo/bar/test/css
foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

返されるコマンドが欲しい:

XYZ
ABC
DEF
GHI

基本的に、wp-content/plugins /内にあるフォルダーを探しています

findを使用すると最も近くなりますが、-maxdepthを使用することはできません。これは、フォルダーが検索する場所から離れているためです。

以下を実行すると、すべての子ディレクトリが再帰的に返されます。

find -type d -path *wp-content/plugins/*

foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI
13
Nick

-Pruneを追加するだけで、見つかったディレクトリが次のディレクトリに移動しません。

find . -type d -path '*/wp-content/plugins/*' -Prune -print

この*wp-content/plugins/*はシェルグロブでもあるため、引用する必要があります。

GNU findを使用して、フルパスではなくディレクトリ名のみが必要な場合は、-print-printf '%f\n'に置き換えるか、ファイルパスに改行文字が含まれていない場合は、上記のコマンドの出力をawk -F / '{print $NF}'またはsed 's|.*/||'にパイプしてください(ファイルパスに有効な文字のみが含まれていることも想定しています)。

zshの場合:

printf '%s\n' **/wp-content/plugins/*(D/:t)

**/は、任意のレベルのサブディレクトリです(初夜のzshに由来する機能であり、ksh93tcshfishbashyashただし、一般的にはいくつかのオプションがあります)、(/)はタイプdirectoryDのファイルのみを選択します非表示(ドット)のものを含め、:ttail(ファイル名)を取得します。

14

find再帰を行うことができます。

find / -type d -path *wp-content/plugins -exec find {} -maxdepth 1 -mindepth 1 -type d \;
4
DopeGhoti

バッシュ的に:

shopt -s globstar
printf "%s\n" **/wp-content/plugins/*

プリント:

bat/bar/foo/blog/wp-content/plugins/GHI
baz/wp-content/plugins/ABC
baz/wp-content/plugins/DEF
foo/bar/wp-content/plugins/XYZ

または

shopt -s globstar
for d in **/wp-content/plugins/*; do printf "%s\n" ${d##*/}; done

プリント:

GHI
ABC
DEF
XYZ
4
Jeff Schaller

treeコマンドは、まさにこの目的のために設計されています。深さは-Lフラグで制御できます。これは、私が管理しているローカルWordpressサイトの例です。

$ tree -L 1 wp-content/
wp-content/
├── index.php
├── plugins
└── themes

2 directories, 1 file

$ tree -L 2 wp-content/
wp-content/
├── index.php
├── plugins
│   ├── akismet
│   ├── contact-form-7
│   ├── index.php
│   └── wordpress-seo
└── themes
    ├── index.php
    ├── twentyfifteen
    └── twentysixteen

11 directories, 3 files

$ tree -L 1 wp-content/plugins/
wp-content/plugins/
├── akismet
├── contact-form-7
├── index.php
└── wordpress-seo

5 directories, 1 file
3
dotancohen

Bashの場合:シンプル(spacesおよびnewlinesでファイル/ディレクトリに対して機能):

shopt -s globstar                    # allow ** for several dirs.
a=(**/wp-content/plugins/*/)         # capture only wanted dirs.
a=("${a[@]%/}")                      # remove trailing slash (dirs) `/`.
printf '%s\n' "${a[@]##*/}"          # print only the last dir name.

印刷されます:

GHI
ABC
DEF
XYZ

ファイルが作成されていても。

3
Isaac

DopeGhotiの答えに基づいて、マッチングのループはどうですか?

find / -type d -iregex '.*/wp-content/plugins' -print0 | while read -r -d $'\0' D; do
    find "$D" -maxdepth 2 -mindepth 1
done

この方法で行う理由は、複数の-execを使用すると混乱/扱いにくくなる一方で、\ n ''などを含む固有のファイル名の問題を回避できるためです。-print0では、結果の間にnull区切り文字が使用されます。

1
Ed Neville

あなたが始めたことに基づいて:

find -type d -path *wp-content/plugins/* | egrep -o "wp-content/plugins/[^/]+($|/)" | sed -r "s~wp-content/plugins/([^/]+)($|/)~\1~" | uniq  

egrepグラブ* wp-content/plugins/*および次のスラッシュまでの任意の文字/または行末$-必要な部分を含みます。

sed、〜区切り文字を使用して、括弧()の最初のセットを使用して必要な部分を選択し、すべての置換として\ 1(必要なもの)を使用します

niq重複する結果を除外します

0
MikeD