在/bin/sh
脚本中,我想检查目录是否只包含一个子目录而不包含其他文件(当然除了“。”和“..”)。我可以解析ls
的输出,但我也明白这通常是一个坏主意。建议?
问题的原因:当我zip
一个文件夹,比如一台Windows机器,我在Linux下解压缩时,有时我会得到一个目录,其内容是原始文件夹的内容;有时我得到一个目录只包含一个子目录,其内容是原始文件夹的内容。 (我假设我在Windows下使用zip
的方式有所不同,或者我使用的各种Windows机器配置略有不同,或者......谁知道?)不管怎样,我想,在Linux方面,以大致相同的方式处理这两种结果,因此这个问题。
对于那些想“如果你的Windows端文件夹真的 只包含一个子目录怎么办?”,那么在这种情况下就好了,虽然我认为这是一个角落的情况。问题规范。
答案 0 :(得分:4)
public class HackHornets_Roster
{
enum MembershipStat {CoPresident, Secretary, Treasurer, RegMember,Sponser}
public static void main (String[] args)
{
final int CoPresidents = 2;
// declare members
MembershipStat ChaseW;
MembershipStat Saif;
MembershipStat MrLee;
MembershipStat Rahil;
MembershipStat Donovon;
MembershipStat Elliot;
MembershipStat Armaan;
MembershipStat JacksonM;
MembershipStat Cyrus;
MembershipStat Avery;
MembershipStat PeterM;
MembershipStat Mahdi;
MembershipStat GeorgeW;
// assign Member Roles
ChaseW = MembershipStat.CoPresident;
Saif = MembershipStat.CoPresident;
MrLee = MembershipStat.Sponser;
Rahil = MembershipStat.Secretary;
Donovon = MembershipStat.RegMember;
Armaan = MembershipStat.RegMember;
Elliot = MembershipStat.RegMember; // Marching Band
JacksonM = MembershipStat.Treasurer;
Cyrus = MembershipStat.RegMember; // sports
Avery = MembershipStat.RegMember; // sports
PeterM = MembershipStat.RegMember; // sports
Mahdi = MembershipStat.RegMember;
GeorgeW = MembershipStat.RegMember;
System.out.println("Chase Williams: " + ChaseW);
System.out.println("Saif Ali: " + Saif);
}
}
将是一个很好的工具。它有一些巧妙的论点:
find
因此不会递归搜索-maxdepth 1
仅搜索目录-type d
用奇怪的文件名解决问题(打印-printf 1
而不是文件名)然后是完整的命令:
1
这将为每个目录和目录本身打印一个字符,这样您就可以查找打印两个字符的目录(find有一个很好的功能,在搜索时忽略find DIRECTORY -maxdepth 1 -type d -printf 1
和.
。
然后,您要检查是否没有其他(非目录)文件:
..
全面检查将是:
find DIRECTORY -maxdepth 1 ! -type d -printf 1
或者,您可以使用if [ "$(find DIRECTORY -maxdepth 1 -type d -printf 1 | wc -m)" -eq 2 \
-a "$(find DIRECTORY -maxdepth 1 ! -type d -printf 1 | wc -m)" -eq 0 ]; then
# It has only one subdirectory and no other content
fi
的{{1}}创建一个命令,打印文件类型(-printf
用于目录):
%y
答案 1 :(得分:1)
/bin/sh
中您遇到的最大问题是隐身文件,因为*
无法捕获[默认]。
我认为这会做你想做的事情:
#!/bin/bash
count_()
{
echo $(( $# - 2 )) # -2 to remove . and ..
}
count()
{
count_ * .*
}
ITEM_COUNT=$(count)
当然,如果您愿意,您可以根据路径进行调整。
示例输出:
bash-3.2$ count
3
bash-3.2$ ll
total 0
drwxr-xr-x 5 christopher wheel 170 Mar 18 2014 .
drwxrwxrwx 6 root wheel 204 Jul 5 12:28 ..
drwxr-xr-x 14 christopher wheel 476 Mar 18 2014 .git
drwxr-xr-x 5 christopher wheel 170 Mar 18 2014 bin
drwxr-xr-x 4 christopher wheel 136 Mar 18 2014 pylib
另一个例子:
sh-3.2$ count_()
> {
> echo $(( $# - 2 )) # -2 to remove . and ..
> }
sh-3.2$ count()
> {
> count_ * .*
> }
sh-3.2$ ITEM_COUNT=$(count)
sh-3.2$ echo ${ITEM_COUNT}
3
<强>旁注:强>
你说不同的拉链实现处理方式不同,但在Linux上,许多工具以不同的方式处理zip /path/to/folder
和zip /path/to/folder/
(这是荒谬的烦人的)。如果您在受控环境中工作,则可能需要规范化压缩事件的方式。但是,如果这是一个面向用户的事情,那就太糟糕了。
如果你没有使用bash
作为调用shell:
countFiles.sh
:
#!/bin/bash
count_()
{
echo $(( $# - 2 )) # -2 to remove . and ..
}
count_ * .*
scriptThatWantsTheCountOfFiles
:
#!/bin/tcsh
set count = `./countFiles.sh`
答案 2 :(得分:0)
为避免必须自行解析输出,您可以使用find
。
if [[ `find . -type d | wc -l` -eq 2 && \
`find . -type f | wc -l` -eq 0 ]]; then
echo yes
else
echo no
fi
如果您想避免递归到目录,可以指定-maxdepth 1
。
有关其他一些选项,请参阅man
find
。
答案 3 :(得分:0)
指向目录inode的链接数量可以有所帮助,但不能完全解决问题。一个目录有2 + n
个指向它的链接,n
内部创建的子目录数。因此,如果您尝试查找仅包含3
个链接的所有目录,那么您将获得仅包含一个子目录的目录。但获取无文件目录的唯一解决方案是搜索它。
也许你可以在混合的两阶段解决方案中思考,首先你会发现所有带有3
链接的目录指向它们(非常有效)。然后你只读那些,发现里面没有普通文件。
答案 4 :(得分:0)
这是一个便携式shell函数,在Dash中测试:
check() {
d=
for i in "$1"/* "$1"/.*
do
test ddd != "$d" && test -d "$i" || return 1
d=d$d
done
test ddd = "$d"
}
我们使用变量d
来计算我们看到的目录数量。我们期待三个(.
,..
和目标目录。如果我们已经看过三个,那就提前退出;同样,如果我们看到一个非目录。
如果我们到循环结束,我们检查我们已经看到三个目录; test
的返回值成为函数的返回值。