Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何使用shell脚本计算目录中的隐藏文件?_Bash_Shell_Scripting_Grep - Fatal编程技术网

Bash 如何使用shell脚本计算目录中的隐藏文件?

Bash 如何使用shell脚本计算目录中的隐藏文件?,bash,shell,scripting,grep,Bash,Shell,Scripting,Grep,我用过这个代码 #!/bin/bash ls -l echo -n "Number of simple files : " ls -l | egrep '^-' | wc -l echo -n "Number of directories : " ls -l | egrep '^d' | wc -l echo -n "Number of hidden files : " ls -la | egrep '^.*\.$' | wc -l echo -n "Number of hidden dir

我用过这个代码

#!/bin/bash

ls -l
echo -n "Number of simple files : "
ls -l | egrep '^-' | wc -l 
echo -n "Number of directories : "
ls -l | egrep '^d' | wc -l
echo -n "Number of hidden files : "
ls -la | egrep '^.*\.$' | wc -l
echo -n "Number of hidden directories : "
ls -la | egrep '^d.*\.$' | wc -l
echo " End"
虽然我能理解前两个白鹭是如何工作的,但我不知道最后一个是如何工作的 两份工作。更具体地说,这意味着什么?
我想要一个以开头的文件。(隐藏文件)然后我应该如何塑造我的正则表达式?

请注意,您为此解析
ls
输出的方法是错误的。请参阅@Dharles Duffy的答案,了解更好的选择。要回答您的问题并稍微解释一下正则表达式:

“^.*\.$”意思是

^     // From the beginning of the string
.*    // match zero or more of any character
\.    // match one literal full-stop
$     // end of the string
我不知道你说的“秘密”文件是什么意思,但如果你说的是隐藏文件,即以
开头,然后是文件名的文件,那么到regex的方法就是

'^\..*$'

请注意,这不是在解析
ls
输出时进行的,它只是用于文件名或目录名,不区分两者。

正则表达式不起作用,因为
'^..*\.$'
匹配行末尾的点。使用以下命令来计算隐藏的文件和目录:

ls -ld .* | egrep '^-' | wc -l
ls -ld .* | egrep '^d' | wc -l
请注意,
egrep'^d'
也匹配
,因此需要从结果中减去2:

ls -ld .* | egrep '^d' | wc -l | awk '{print $1 - 2}'
备选方案:

ls -ld .* | egrep '^d' | tail -n +3 | wc -l
echo $(($(ls -ld .* | egrep '^d' | wc -l) - 2))

如果可以的话,如果你想找到符号链接,你可以使用-L。

你根本不应该使用
grep
(或
ls
)来完成这个任务。有关如何将
ls
用于人类交互式显示的深入讨论,请参阅

all_files=( * )            # includes directories
directories=( */ )         # directories only
hidden_files=( .* )        # includes directories
hidden_directories=( .*/ ) # directories only

echo "Number of files: $(( ${#all_files[@]} - ${#all_directories[@]} ))"
echo "Number of directories: ${#directories[@]}"
echo "Number of hidden files: $(( ${#hidden_files[@]} - ${#hidden_directories[@]} ))"
echo "Number of hidden directories: $(( ${#hidden_directories[@]} - 2 ))"

上一次计算中的
-2
将删除始终存在的

最后两项工作不正确,但

ls -la | egrep '^.*\.$' | wc -l
ls -la | egrep '^d.*\.$' | wc -l
返回2

ls -la | egrep '^.*\.$' 
ls -la | egrep '^d.*\.$' 
返回

drwxr-xr-x  7 root root  4096 date time .
drwxr-xr-x 31 root root  4096 date time ..
变体:

secret files:
ls -la | grep '^-' |awk '{print $9}' |egrep '^\.[^\.]' |wc -l
secret dirs:
ls -la | grep '^d' |awk '{print $9}' |egrep '^\.[^\.]' |wc -l

是的,对不起,我是说隐藏。我真的不明白为什么我的示例适用于隐藏文件(这不是我的代码)。您的示例似乎更符合逻辑。不,您的原始文章中的最后两个正则表达式将始终匹配,并且仅匹配
分别是“此目录”和“父目录”的引用。因此,无论应用到哪个文件夹,结果都将始终为2。在你的例子中,可能是巧合,你有两个隐藏的文件和目录。我的意思是你的解决方案
“^\..*$”
。奇怪的是,我的例子确实有效,但我不明白为什么。@Molnia我测试了你的代码,但它对我无效。它总是返回2,因为它匹配
。是的,我认为你是对的。这让我很困惑,你为什么这么认为?预期值和实际值是多少?我有3个隐藏目录,但事实上我只有一个。也许,它会计算
为什么要告诉
find
打印实际姓名,而你只想计算姓名
-printf。
将允许您计数字符,或者
-printf'\n'
将允许您计数通过管道的数据较少的行,因此效率较低……而且,
wc--lines
仅在GNU系统上工作,而
wc-l
在任何POSIX兼容平台上工作。为什么呢?感谢您的见解:)现在,如果您真正的问题不是如何计算隐藏文件,而是regex
^.*.\.$
的含义,那么您应该将其作为自己的独立问题来问。最后两个问题不起作用。它们分别计算以句号结尾的常规文件和目录的数量。对于这里的任何其他人来说,freenode#bash channel:维护的wiki的一些链接提供了计算一般文件的最佳实践方法。详细描述了为什么不应在此类用例中使用
ls
,以及可用的替代方案。
$(${{所有#u文件[@]}-${所有#u目录[@]})
$(${所有#u文件[@]}-${所有#u目录[@]})”
(缺少括号)谢谢您,jaypal,感谢您按照@Gergoosi的建议进行编辑
secret files:
ls -la | grep '^-' |awk '{print $9}' |egrep '^\.[^\.]' |wc -l
secret dirs:
ls -la | grep '^d' |awk '{print $9}' |egrep '^\.[^\.]' |wc -l