Unix Bash Shell脚本文件大小

Unix Bash Shell脚本文件大小,bash,file,shell,unix,Bash,File,Shell,Unix,我正在编写一个bashshell脚本,它要求我在给定目录中按大小顺序显示文件。如果文件大小为0,我将询问用户是否要删除它。到目前为止,我有: #!/bin/bash FILE=$(ls -S $1) for FIL in ${FILE} do echo ${FIL} done 这将按大小顺序显示文件,但我不确定如何提示用户删除大小为0的文件 谢谢你的帮助 这可以测试一个文件大小是否为0(您只需要将其包含在循环中) 因此,如果我们希望尽可能接近您当前的方法,我们可以这样做: #!/bin

我正在编写一个bashshell脚本,它要求我在给定目录中按大小顺序显示文件。如果文件大小为0,我将询问用户是否要删除它。到目前为止,我有:

#!/bin/bash
FILE=$(ls -S $1)
for FIL in ${FILE}
do
    echo ${FIL}
done
这将按大小顺序显示文件,但我不确定如何提示用户删除大小为0的文件


谢谢你的帮助

这可以测试一个文件大小是否为0(您只需要将其包含在循环中)


因此,如果我们希望尽可能接近您当前的方法,我们可以这样做:

#!/bin/bash
FILE="$(ls -S "$1")"

for f in $FILE
do
    file_size_bytes=$(du "$f" | cut -f1)
    echo "$f"

    if [[ "$file_size_bytes" -eq 0 ]]
    then
        read -r -p "Would you like to delete the zero-byte file ${f}? [Y/n]: " input

        if [[ "$input" = [Yy] ]]
        then
            rm "$f"
        fi
    fi
done
另一个答案是使用
stat
,但是
stat
不是POSIX或便携式的,但是如果您只在Linux下运行,
stat
是一个很好的方法

在上面的示例中,
read-p
用于提示用户输入,并将结果存储在
$input
中。我们使用
[[“$input”=[Yy]]]
查看输入是
Y
还是
Y

按照当前的写入方式,您必须键入
y
y
,然后按enter键删除该文件。如果您希望它在用户点击
y
y
时立即发生,请将
-n1
添加到
read
以使其仅读取一个字符

您也不需要使用
${var}
,除非您将它放在另一个字符串中,或者如果您需要使用某种参数扩展

作为旁注,这听起来像是某种类型的家庭作业或学习经验,因此,请查阅上面的每个命令、选项和语法元素,真正了解它是如何工作的

find /your/path/ -size 0 -exec echo rm -i {} \; # will fail if there are spaces in any file names
更好的方法:

find /your/path/ -size 0 -print0 | xargs -0 rm -i
删除回显以删除文件


谢谢@Will,@AdamKatz。

您可以使用
重定向
并将
stdin
重定向到另一个文件描述符,同时为循环提供进程替换以实现您的目标。e、 g:

#!/bin/bash

[ -z "$1" ] && {
    printf "error: insufficient input, usage: %s <path>\n" "${0//*\/}"
    exit 0;
}

exec 3<&0   # temprorary redirection of stdin to fd 3

while read -r line; do
    printf " rm '%s' ? " "$line"
    read -u 3 ans   # read answer for fd 3
    anslower="${ans,,}"
    if [ "${anslower:0:1}" = "y" ]; then
        printf " %s  =>  removed.\n" "$line"
        # rm "$line"
    else
        printf " %s  =>  unchanged.\n" "$line"
    fi
done < <(find "$1" -type f -size 0)

exec 3<&-   # close temporary redirection

这并没有回答提示。我想用xargs也能得到同样的答案:find/your/path/-size 0 | xargs-p-I{}rm-f{}\@Will可以只使用
rm-i
?我可以将此方法用于for循环中的FIL而不是路径吗?我尝试用FIL替换路径,但得到了一个“预期的条件二进制运算符”错误。#/bin/bash FILE=$(ls-S$1)对于$FILE中的FIL do if[[find FIL-size 0]]然后回显零fi done当我尝试此操作时,第一行出现“非法选项--c”错误,第一行出现“预期一元运算符”错误。当我在stat上运行man时,我没有看到显示-c选项。@t这是什么操作系统?
--printf“%s”
有效吗?但是,是的,
stat
不是很好移植,主要是Linux的东西。这就是我选择du-b的原因;是POSIX!:)我在手册页中没有看到du的-b选项。我应该指定操作系统,我在我的Mac上运行El Capitan。啊,我在约塞米蒂Mac上有它;奇怪。您只需取下
-b
,它也能正常工作;“字节”是默认行为“.我只是在回答时把它去掉了。没有
-b
无论如何都会更便于携带。抢手货我删除了-b,不再看到错误,但是当我运行脚本时,我的屏幕上充满了整数。我删除了嵌套的if,这样我就可以让外部if先工作。在“then”行后面的外部if中,我添加了“echo zero”。我不知道这些数字是从哪里来的:/如果您的文件名中有空格,
表示$FILE中的f
,会发生什么?也许看看设置
IFS
?好吧,OP解析了
ls
的输出;我不知道<代码>shellcheck比这更好地警告了我;)但目标是对OP的解决方案进行最小的更改。如果是我,我也会使用相同的命令管道获取大小和文件名,然后在
IFS=while read line
。可以添加类似于
-printf“%s%p\n”| sort-rn
的内容以匹配排序方面的问题。。
#!/bin/bash

[ -z "$1" ] && {
    printf "error: insufficient input, usage: %s <path>\n" "${0//*\/}"
    exit 0;
}

exec 3<&0   # temprorary redirection of stdin to fd 3

while read -r line; do
    printf " rm '%s' ? " "$line"
    read -u 3 ans   # read answer for fd 3
    anslower="${ans,,}"
    if [ "${anslower:0:1}" = "y" ]; then
        printf " %s  =>  removed.\n" "$line"
        # rm "$line"
    else
        printf " %s  =>  unchanged.\n" "$line"
    fi
done < <(find "$1" -type f -size 0)

exec 3<&-   # close temporary redirection
$ bash findzerosz.sh ../tmp/stack/dat/tmp/tst/tdir
 rm '../tmp/stack/dat/tmp/tst/tdir/file4.html' ? n
 ../tmp/stack/dat/tmp/tst/tdir/file4.html  =>  unchanged.
 rm '../tmp/stack/dat/tmp/tst/tdir/file1.html' ? y
 ../tmp/stack/dat/tmp/tst/tdir/file1.html  =>  removed.
 rm '../tmp/stack/dat/tmp/tst/tdir/file2.html' ? y
 ../tmp/stack/dat/tmp/tst/tdir/file2.html  =>  removed.
 rm '../tmp/stack/dat/tmp/tst/tdir/file3.html' ? Y
 ../tmp/stack/dat/tmp/tst/tdir/file3.html  =>  removed.
 rm '../tmp/stack/dat/tmp/tst/tdir/file5.html' ? n
 ../tmp/stack/dat/tmp/tst/tdir/file5.html  =>  unchanged.