5

たとえば、最初に現在のディレクトリ内のファイルを出力し、次にサブディレクトリまたはサブディレクトリ内のファイルなどを常にその深さまで表示します。

4

5 に答える 5

9

find の "-printf" 機能を sort と組み合わせて使用​​します。自分で見て:

find . -printf "%d %p\n"|sort -n

深さでソートされたリストを生成します (最初の列に深さを表示し、2 番目の列にファイル パスを表示します)。これは私の現在のディレクトリに印刷されます:

0 .
1 ./bin
1 ./log
1 ./templates
2 ./bin/cc_env
3 ./files/test/mail.txt

最初の列を削除したい場合は、perl を使用できます。

find . -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;'

そして、あなたが行きます。perl フィルターは先頭の数字をすべて削除します。ディレクトリ自体を省略したい場合は、'-type f' パラメータを使用します。

find . -type f -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;'

ヒント: printf %d のようなトリックについては、find マンページを調べてください。

于 2016-10-14T09:23:55.320 に答える
4

最も簡単な解決策:

$ echo * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*
a a/b a/b/c a/b/c/d1 a/b/c/d2 a/b/c/d1/e a/b/c/d2/e a/b/c/d1/e/f a/b/c/d2/e/f

または、列で:

$ echo * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/* |tr ' ' '\n'
a
a/b
a/b/c
a/b/c/d1
a/b/c/d2
a/b/c/d1/e
a/b/c/d2/e
a/b/c/d1/e/f
a/b/c/d2/e/f

ツリーの深さはこの例ではハードコーディングされていますが、小さなスクリプトを記述してより柔軟にすることができます。

A="*"
while true
do
  B=$(echo $A)
  [ "$B" = "$A" ] && break
  echo $B
  A="$A/*"
done | tr ' ' '\n'

使用例:

$ A="*"; while true; do B=$(echo $A); [ "$B" = "$A" ] && break; echo $B; A="$A/*"; done | tr ' ' '\n'
a
a/b
a/b/c
a/b/c/d1
a/b/c/d2
a/b/c/d1/e
a/b/c/d2/e
a/b/c/d1/e/f
a/b/c/d2/e/f

ツリーの例を次に示します。

$ mkdir -p a/b/c/d{1,2}/e/f
$ tree .
.
└── a
    └── b
        └── c
            ├── d1
            │   └── e
            │       └── f
            └── d2
                └── e
                    └── f

9 directories, 0 files

findサブツリーを次々に表示するため、検索/深度ソリューションは明らかに機能しません。キーは、-depthサブツリーを表示する必要がある方向を示します。しかし、もちろん、出力が深さでソートされるという意味ではありません。

$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d2
./a/b/c/d2/e
./a/b/c/d2/e/f
./a/b/c/d1
./a/b/c/d1/e
./a/b/c/d1/e/f

$ find . -depth
./a/b/c/d2/e/f
./a/b/c/d2/e
./a/b/c/d2
./a/b/c/d1/e/f
./a/b/c/d1/e
./a/b/c/d1
./a/b/c
./a/b
./a
.

ご覧のとおり、どちらの場合も答えは正しくありません ( がある場合とない場合-find)。

于 2012-07-30T05:17:46.860 に答える
3

もっともらしい手法はfind、ファイルのパス名を生成するために使用し、パス内のスラッシュの数が名前の前に来るようにファイル名を処理し、スラッシュの数 (深さ) で並べ替え、次に名前で並べ替えることができます。 . 簡単な解決策は、ファイル名に改行がないことを前提としています (他のスペースや奇妙なボール文字は関係ありません)。興味深い/トリッキーな部分は、特定の行のスラッシュの数を数えるクリーンな方法を見つけることです。

find . -type f -print |
perl -n -e '$x = $_; $x =~ tr%/%%cd; print length($x), " $_";' |
sort -k 1n -k 2 |
sed 's/^[0-9][0-9]* //'

その Perl を書くためのもっとコンパクトな方法があるかもしれませんが、それはうまくいきます。

于 2012-07-28T20:40:58.677 に答える
1

関数を使用してファイルシステムを再帰的にトラバースします

test.sh:

#!/bin/bash

function traverse() {
    find $1 -mindepth 1 -maxdepth 1 ! -type d -exec echo "$2"{} \; 
    for d in $(find $1 -mindepth 1 -maxdepth 1 -type d ! -name ".")
    do
        # if you just need files comment out next line
        echo "$2$d"
        traverse "$d" "${2}  "
    done
}

traverse $1

使用法:
./test.sh dir
出力を提供します:

./test.sh
./testA
  ./testA/dat2
  ./testA/dat1
  ./testA/testB
    ./testA/testB/dat4
./testC
  ./testC/dat3
于 2012-07-28T21:04:43.133 に答える
0

find次のコマンドを使用します。

find . -depth

からman find:

-depth ディレクトリ自体の前に各ディレクトリの内容を処理します。

于 2012-07-28T19:27:17.973 に答える