如何检查Bash中文件是否为空?


183

我有一个名为diff.txt的文件。要检查它是否为空。做了这样的事情,但无法正常工作。

if [ -s diff.txt ]
then
        touch empty.txt
        rm full.txt
else
        touch full.txt
        rm emtpy.txt
fi

24
[-s FILE]如果FILE存在且大小大于零,则为true。因此,如果“ diff.txt”不为空,则会得到“ empty.txt”。
Matthias

2
PS:如果您要检查实际diff通话,只需检查返回值:if diff foo.txt bar.txt; then echo 'No difference'
l0b0

20
测试可以否定:if [ ! -s diff.txt ]; then echo "IS EMPTY";else echo "HAS SOMETHING";fi
David Ramirez 2014年

当心尾随换行符。使用$ cat diff.txt | hexdump -C
Alejandro Blasco

Answers:


225

拼写令人讨厌,不是吗?检查的拼写empty,然后尝试以下操作:

#!/bin/bash -e

if [ -s diff.txt ]
then
        rm -f empty.txt
        touch full.txt
else
        rm -f full.txt
        touch empty.txt
fi

我非常喜欢shell脚本,但是它的一个缺点是,当您拼写错误时,shell无法帮助您,而像C ++编译器这样的编译器可以为您提供帮助。

顺便注意一下,正如@Matthias所建议的,我已经互换了empty.txtand 的角色full.txt


6
该外壳可以帮助解决拼写错误。 empty=empty.txt; full=full.txt; diff=diff.txt; if [ -s ${diff?} ]; then r=${empty?} t=${full?}; else r=${full?} t=${empty?}; fi; rm ${r?}; touch ${t?}
威廉·珀塞尔

1
使用工具shellcheck可以很好地找到拼写错误。
2016年

1
如果文件也不存在,这肯定会失败吗?应该检查文件是否为空。
geedoubleya

@geedoubleya:好的。这是合理的一点。如果文件的存在是相关的(当然也可能),那么可以相应地调整脚本。如果您将调整后的脚本作为答案并对其进行ping操作,我会投票赞成。
thb

1
您还可以set -u
Jon McClung

70
[ -s file.name ] || echo "file is empty"

8
[[-s file.name]] && echo“ full” || 回声“空”
McPeppr

1
[[ -s file.name ]] || { [[ -f file.name ]] && echo 'empty' || echo 'does not exist'; }
smarber

53

[[-s file]]->检查文件的大小是否大于0

if [[ -s diff.txt ]]; then echo "file has something"; else echo "file is empty"; fi

如果需要,这将检查当前目录中的所有* .txt文件;并报告所有空文件:

for file in *.txt; do if [[ ! -s $file ]]; then echo $file; fi; done

3
您不需要做$(ls *.txt,实际上也不需要。有些人已经为ls使用长格式的默认设置进行了设置(例如我),并且外壳程序已经可以*.txt自行扩展。只是做for file in *.txt
莉莉丝

真好!如果您想递归检查所有txt文件,则可以这样使用findfor file in $(find . -name '*.txt'); do if [[ ! -s $file ]]; then echo $file; fi; done
KlimczakM

1
仅仅因为这种可怕的反模式而被否决了for file in $(ls *.txt); do。请for file in *.txt; do改为使用;请阅读此Bash陷阱页面 ; 并停止传播此类反模式。
gniourf_gniourf

8

尽管其他答案正确,但使用该"-s"选项还将显示文件为空,即使该文件不存在。
通过添加此附加检查"-f"来首先查看文件是否存在,我们确保结果正确。

if [ -f diff.txt ]
then
  if [ -s diff.txt ]
  then
    rm -f empty.txt
    touch full.txt
  else
    rm -f full.txt
    touch empty.txt
  fi
else
  echo "File diff.txt does not exist"
fi

4

@geedoubleya的答案是我的最爱。

但是,我确实喜欢这个

if [[ -f diff.txt && -s diff.txt ]]
then
  rm -f empty.txt
  touch full.txt
elif [[ -f diff.txt && ! -s diff.txt ]]
then
  rm -f full.txt
  touch empty.txt
else
  echo "File diff.txt does not exist"
fi

3

要检查文件是否为空或只有空格,可以使用grep:

if [[ -z $(grep '[^[:space:]]' $filename) ]] ; then
  echo "Empty file" 
  ...
fi

这是唯一的好答案,应该被接受。使用-s不能回答问题。它查找确实存在且大小大于0个字节的文件。
Akito

2

许多答案都是正确的,但我觉得它们可能更完整/更简单,例如:

示例1:基本的if语句

# BASH4+ example on Linux :

typeset read_file="/tmp/some-file.txt"
if [ ! -s "${read_file}" ]  || [ ! -f "${read_file}" ] ;then
    echo "Error: file (${read_file}) not found.. "
    exit 7
fi

如果$ read_file为空或不存在,则停止显示并退出。我不止一次地误读了这里的最高答案,这意味着相反。

示例2:作为函数

# -- Check if file is missing /or empty --
# Globals: None
# Arguments: file name
# Returns: Bool
# --
is_file_empty_or_missing() {
    [[ ! -f "${1}" || ! -s "${1}" ]] && return 0 || return 1
}


0

我来这里是为了寻找如何删除空__init__.py文件,因为它们在Python 3.3+中是隐式的,最终使用:

find -depth '(' -type f  -name __init__.py ')' -print0 |
  while IFS= read -d '' -r file; do if [[ ! -s $file ]]; then rm $file; fi; done

另外(至少在zsh中)使用$ path作为变量也会破坏$ PATH环境,因此会破坏打开的外壳。无论如何,以为我会分享!


0

检查文件是否为空的最简单方法:

if [ -s /path-to-file/filename.txt ]
then
     echo "File is not empty"
else
     echo "File is empty"
fi

您也可以将其写在一行上:

[ -s /path-to-file/filename.txt ] && echo "File is not empty" || echo "File is empty"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.