我正在尝试使用GNU find来查找不包含其他目录的目录,但可能包含也可能不包含常规文件。
到目前为止,我最好的猜测是:
find dir -type d \( -not -exec ls -dA ';' \)
但这只是给我一长串“。”
谢谢!
答案 0 :(得分:71)
如果您的文件系统符合POSIX,则可以使用-links(即,目录中包含每个子目录的链接,来自其父目录的链接和指向self的链接,因此如果没有子目录,则计数为2个链接)。
以下命令应该执行您想要的操作:
find dir -type d -links 2
然而,它似乎不适用于Mac OS X(正如@Piotr所提到的)。这是另一个版本,速度较慢,但可以在Mac OS X上运行。它基于他的版本,并通过更正来处理目录名称中的空格:
find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;
答案 1 :(得分:5)
我刚刚发现了另一个适用于Linux和Linux的解决方案。 macOS(没有find -exec
)!
它涉及sort
(两次)和awk
:
find dir -type d | sort -r | awk 'a!~"^"$0{a=$0;print}' | sort
按相反顺序对find
输出进行排序
如果当前行是前一行的前缀,则使用awk
省略行
sort
他们(所以它看起来像普通的find
输出)答案 2 :(得分:2)
find . -type d -print0 | xargs -0 -IXXX sh -c '(ls -p XXX | grep / >/dev/null) || echo XXX' ;
说明:
ls -p
以'/'(ls -p XXX | grep / >/dev/null)
会返回0 -print0
&& -0
是使xargs处理目录名中的空格答案 3 :(得分:0)
这个怎么样?它是便携式的,它不依赖于finnicky链接计数。但请注意,将find root/folder -type d | awk '{ if (length($0)<length(prev) || substr($0,1,length(prev))!=prev) print prev; prev=($0 "/") } END { print prev }'
放在尾随/。
NSTimeInterval time1 = [[NSDate date] timeIntervalSince1970];
unsigned long long bytesOfDownloading1 = 0;
答案 4 :(得分:0)
这是适用于Linux和OS X的解决方案:
find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' \;
或:
struct HoldStuff {
std::vector<StuffItem> items;
std::set<StuffItem, StuffItemComparator> sorted_items;
}
答案 5 :(得分:0)
我的目录树中有一些名称奇怪的文件,它们使awk
像
@AhmetAlpBalkan的答案。所以我采用了稍微不同的方法
p=;
while read c;
do
l=${#c};
f=${p:0:$l};
if [ "$f" != "$c" ]; then
echo $c;
fi;
p=$c;
done < <(find . -type d | sort -r)
与awk
解决方案中一样,我进行反向排序。这样,如果目录路径是上一个匹配项的子路径,则可以轻松地辨别。
这里p
是我以前的比赛,c
是当前比赛,l
是当前比赛的长度,f
是第一个l
上一个匹配的匹配字符。我只echo
那些与上一场比赛的开始不符的匹配。
提供的awk
解决方案的问题是,如果路径名在某些子目录的名称中包含诸如+
之类的东西,则字符串开头的匹配似乎会引起混淆。这导致awk
为我返回了一些误报。
答案 6 :(得分:0)
此awk
/ sort
管道比最初建议的in this answer更好,但是在很大程度上基于它:)无论路径是否包含,它都将更可靠地工作regex特殊字符与否:
find . -type d | sort -r | awk 'index(a,$0)!=1{a=$0;print}' | sort
请记住,awk
字符串是1索引而不是0索引,如果您习惯使用基于C的语言,这可能很奇怪。
如果当前行在上一行中的索引为1(即从该行开始),则我们将其跳过,就像"^"$0
的匹配项一样。