bash中是否有一种方法可以从深度顺序对目录中的文件进行排序,例如首先打印当前目录中的文件,然后打印子目录或子目录中的文件,依此类推,他们的深度。
答案 0 :(得分: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
)。
答案 1 :(得分:4)
将find的“-printf”功能与sort结合使用。亲眼看看:
find . -printf "%d %p\n"|sort -n
它生成深度排序列表(在第一列中显示深度,在第二列中显示文件路径)。这打印在我当前的目录中:
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的技巧。
答案 2 :(得分:2)
一种似是而非的技术会使用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的方式,但是有效。
答案 3 :(得分: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
答案 4 :(得分:0)
使用find
命令:
find . -depth
来自man find
:
-depth在目录本身之前处理每个目录的内容。