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


13

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

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

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

回答:


14

-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早期nightiesでは、今のような他のほとんどのシェルで見つかったksh93tcshfishbashyash、しかし、一般的にいくつかのオプションの下)(/)のみタイプのファイルを選択するために、ディレクトリD非表示(ドット)のものを含めること:t末尾(ファイル名)を取得します。


この検索は、dirsの改行をに変換し?ます。bashの場合、(質問でタグ付けされているように)これは機能します。
sorontar 2017年

@sorontar、find出力?できない文字、または置換文字、またはエスケープの任意の形式を出力する実装は、出力が端末に送られるときにのみ行われ、ここにあるようなパイプに送られるときは行われません。
ステファンChazelas

あなたの答えにある最初の(そしてzsh以外の)コマンドにはパイプがありません。これは私がテストしたコマンドであり、改行を変更するコマンドです。「ファイルパスに改行文字が含まれていないと想定する」と言ったように、パイプ処理されると、改行で失敗することも既に認められています。
sorontar 2017年

@sorontar、申し訳ありません私はあなたが改行を我々が作っているという仮定壊れないようにエスケープされるように、それはOKに働くだろうと言うことで第二部にコメントと思っていたsed/ awkすべてのファイルがオンライン上にあることを。さて、対話型/ターミナル出力のためにABC?BCDまたはABC\nBCDを取得する方が、と呼ばれるdirに対して2 行ABCBCD行を取得するよりも有用であると主張するかもしれません$'ABC\nBCD。ユーザ提示のレベルでだと、私たちはとも呼ばれるファイルのことを指摘できた$'AB\bC'出力が端末になると、あなたが見たいAC、そのようなことなく、?...交換
ステファンChazelas

-pruneを使用して検索し、printfを使用して出力形式を変更すると、正確に私が求めていたものが得られました。パーフェクト-ありがとう!
Nick

4

バッシュ的に:

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

いいえ、dirs内のファイルも印刷します。私の答えを読んでください。
sorontar 2017

いい視点ね; ありがとうございました!私はそれらのディレクトリ構造を再作成しましたが、それらにテストファイルを配置しませんでした。
ジェフシャラー

4

次のようなfind再帰が可能です。

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

3

Bashの場合:シンプル(スペース改行を含むファイル/ディレクトリで機能):

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

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


隠しdotglobディレクトリ内を調べず、隠しファイルをスキップし(不要な場合はオプションを参照)、ディレクトリに加えてディレクトリへのシンボリックリンクを含めます(**bash 4.2以前ではシンボリックリンクもトラバースします)。
ステファンChazelas

@StéphaneChazelas隠しファイル?質問は何も求めず、dirsのみを求めます。はい、隠しディレクトリを個別に選択できます(必要に応じて機能として)。そしてはい、現在のバージョンのbashではシンボリックリンクは横断的ではありません。
sorontar 2017年

1
私のコメントを攻撃的なものと見なさないでください。私はあなたの回答に賛成し、必ずしも明白ではないいくつかの事実を指摘するために下にメモを追加しました。findファイルを除外しません。グロブはドットファイルを除外します。2つの違いとして指摘する価値があります。
ステファンChazelas

3

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

1

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は、結果の間にヌル区切り文字を使用します。


0

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

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(必要なもの)を使用します

uniqは重複する結果を除外します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.