サブディレクトリを含まないディレクトリを見つける


10

スクリプトはkshです。現在のディレクトリの直下にある、サブディレクトリではなくファイルのみを含むすべてのディレクトリ名を検索する必要があります。

ls -alRdディレクトリの)最初のフィールドの最初の文字の出力を使用して再帰的に解析できることを知っています。awk解析して見つけるのに最適な方法だと思います。

たとえばls -al、現在のディレクトリの単純な出力は次のとおりです。

   drwxr-xr-x  22 af      staff    748 18 Mar 22:21 .
   drwxr-xr-x   5 root    admin    170 17 Mar 18:03 ..
   -rw-------   1 af      staff      3 17 Mar 16:37 .CFUserTextEncoding
   drwxr-xr-x   5 af      staff    170 17 Mar 17:12 Public
   drwxr-xr-x   9 af      staff    306 18 Mar 17:40 Sites
   -rw-------   1 af      staff      3 17 Mar 16:37 textd
   

そここの出力の2のディレクトリは、次のとおりPublicSites。ディレクトリにはPublicサブディレクトリが含まれていますが、しませんSitesありません。には3つのサブディレクトリがありますSites。したがって、ディレクトリを含まないディレクトリのみをエコーする必要があります。私の場合、これだけSitesです。

回答:


1

awk全く使う必要はありません。ksh次のような、提供されている組み込みテストを使用します。

#!/bin/ksh

for NAME in *
do
    FOUND=no
    if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
    then
        for SUBNAME in $NAME/*
        do
            if [[ -d $SUBNAME ]]
            then
                FOUND=yes
                break
            fi
        done
        if [[ $FOUND == no ]]
        then
            echo Found only files in $NAME
        fi
    fi
done

この小さなスクリプトは、現在のディレクトリ内のすべてのディレクトリを調べ、サブディレクトリではなくファイルのみが含まれているかどうかを通知します。


14

使用できfind、「通常のUnixファイルシステム」(つまり、find(1)-noleafオプションの説明で定義されているで作業している場合は、次のコマンドを使用できます。

find . -type d -links 2

各ディレクトリには、少なくとも2つの名前(ハードリンク).とその名前があります。そのサブディレクトリは、存在する場合..、親ディレクトリを指しているため、N個のサブディレクトリを持つディレクトリは、ハードリンク数がN + 2になります。したがって、ハードリンクカウントが2のディレクトリを検索すると、サブディレクトリがN = 0のディレクトリが検索されます。

したがって、を使用できる場合find、これは間違いなく最速の方法であり、stat()各メンバーのディレクトリの内容に対するシェル内ループよりも明らかに優れています。


ディレクトリにファイルが含まれている場合、これは機能しないようです。
user394 2018

1
これは、ディレクトリリストのエントリではなく、ディレクトリのiノードを参照するハードリンクに関するものです。たとえば、/some/directoryiノード#12345678がある場合、サブディレクトリがない場合、そのiノードへのハードリンクはちょうど2つ/some/directory/.あり/some/directoryます。ディレクトリにファイルがあるかどうかに関係なく機能します。
telcoM

この点でBTRFSは「通常のUnixファイルシステム」ではないことに言及する価値があります。残念ながら、ディレクトリのリンク数は常に1です。(ただし.foo/..同じinode番号を持っている。)
ピーター・コルド

3

*/現在のディレクトリのサブディレクトリに一致します。これには、ディレクトリへのシンボリックリンクが含まれます。

ksh93では~(N)、パターンの先頭に追加すると、一致がない場合は空のリストに展開されます。これがないと、一致がない場合、パターンは変更されません。

次のksh93関数は、サブディレクトリやディレクトリへのリンクを含まない現在のディレクトリのサブディレクトリをリストします。

list_leaf_directories () {
  local FIGNORE='.?(.)'        # don't ignore dot files
  local d
  for d in */; do
    [[ -L $d ]] || continue;   # skip symbolic links
    set -- ~(N)"$d"/*/
    if ((!$#)); then echo "$d"; fi
  done
done

0

私があなたを誤解していないのであれば、サブディレクトリではなくディレクトリでファイルを見つけたいだけです。これがあなたの意図である場合、ここに解決策があります

find . -type f

通常のファイル(ブロックデバイスファイル、キャラクターデバイスファイルなど)以外を検索する場合は、findコマンドのマニュアルページを参照し、そのページでtypeキーワードを探します。通常のファイルやディレクトリなど、さまざまなファイルタイプが表示されます。

これがあなたが探しているものであることを願っています


いいえ、それはまったく問題ではありません。s / catalogue / directory / gを実行すると、それはかなり明確になります。Nat Kupは、サブディレクトリを含まないディレクトリを探しています。
Gilles「SO-悪をやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.