【问题标题】:ls command and size of files in shell scriptls 命令和 shell 脚本中文件的大小
【发布时间】:2015-11-01 15:14:16
【问题描述】:
count=0;      #count for counting
IFS='
'
for x in `ls -l $input`;     #for loop using ls command
do 
a=$(ls -ls | awk '{print $6}')   #print[6] is sizes of  file
echo $a

b=`echo $a | awk '{split($0,numbers," "); print numbers[1]}'`
echo $b     
if [ $b -eq 0 ]          # b is only  size of a file
then
count=`expr $count + 1`   #if b is zero , the count will increase one by one
fi
echo $count
done

我想找到 0 大小的文件。我使用 find 命令来做到这一点。第二件事是我想使用 ls 命令和 awk 计算大小为 0 的文件的数量。但它不是真正的代码。我的错误是什么?

【问题讨论】:

  • 我不知道其他用法。 ls不是真的吗? @gniourf_gniourf
  • @lurker 即使这样也不推荐,因为如果任何文件名包含换行符,输出的行数不是文件数。
  • @chepner 确实如此,尽管这种情况非常罕见。我会删除我的建议。
  • 我知道这种情况很少见,但我认为公共论坛中的建议应该比您自己使用的代码更注意正确。 (你永远不知道在什么情况下有人会尝试使用你的建议,如果你能避免由于未说明的假设而导致不愉快的意外,那就更好了。)

标签: bash shell awk ls


【解决方案1】:

如果文件大小不为零,-s 测试为真。如果该文件测试失败,请增加您的空文件计数。

empty_files=0   
for f in "$input"/*; do
    [ -s "$f" ] || : $(( empty_files++ ))
done

【讨论】:

    【解决方案2】:

    你的主要错误是你是parsing ls

    如果您想查找(常规)空文件,并且您有支持 -empty 谓词的 find 版本,请使用它:

    find . -type f -empty
    

    请注意,这也会在子文件夹中递归;如果你不想这样,请使用:

    find . -maxdepth 1 -type f -empty
    

    (假设你的find也支持-maxdepth)。

    如果您只想计算有多少空(常规)文件:

    find . -maxdepth 1 -type f -empty -printf x | wc -m
    

    如果您想同时执行这两个操作,即打印出名称或将它们保存在数组中以备将来使用,并计算它们:

    empty_files=()
    while IFS= read -r -d '' f; do
        empty_files+=( "$f" )
    done < <(find . -maxdepth 1 -type f -empty -print0)
    printf 'There are %d empty files:\n' "${#empty_files[@]}"
    printf '   %s\n' "${empty_files[@]}"
    

    在 Bash≥4.4 的情况下,您可以使用 mapfile 代替 while-read 循环:

    mapfile -t -d '' empty_files < <(find . -maxdepth 1 -type f -empty -print0)
    printf 'There are %d empty files:\n' "${#empty_files[@]}"
    printf '   %s\n' "${empty_files[@]}"
    

    对于符合 POSIX 的方式,请使用 test-s 选项:

    find . -type f \! -exec test -s {} \; -print
    

    如果你不想递归到子目录,你必须-prune他们:

    find . \! -name . -prune -type f \! -exec test -s {} \; -print
    

    如果你想数一数:

    find . \! -name . -prune -type f \! -exec test -s {} \; -exec printf x | wc -m
    

    在这里,如果您想执行这两个操作(计算它们并将它们保存在数组中以备后用),请使用之前的while-read 循环(如果您生活在未来,则使用mapfile)用这个find:

    find . \! -name . -prune -type f \! -exec test -s {} \; -exec printf '%s\0' {} \;
    

    另请参阅 chepner's answer 了解纯 shell 解决方案(需要稍作调整以符合 POSIX)。


    关于你的评论

    我想计算并删除[空文件]。我怎样才能同时做到这一点?

    如果你有 GNU find(或支持所有好东西的 find):

    find . -maxdepth 1 -type f -empty -printf x -delete | wc -m
    

    如果没有,

    find . \! -name . -prune -type f \! -exec test -s {} \; -printf x -exec rm {} \; | wc -m
    

    确保-delete(或-exec rm {} \;)谓词位于末尾! 不要交换谓词的顺序!

    【讨论】:

    • 我要统计并删除 0 个字节。我怎样才能同时做到这一点?
    • @esrtr 见帖子底部。