如何在Shell脚本中测试一行是否为空?

42

我有一个如下所示的shell脚本:

cat file | while read line
do
    # run some commands using $line    
done

现在我需要检查这一行是否包含任何非空格字符([\n\t ]),如果没有,则跳过它。 我该怎么做?
7个回答

85

由于默认情况下 read 读取以空格分隔的字段,因此只包含空格的行应将空字符串分配给变量,因此您应该能够使用以下方法跳过空行:

[ -z "$line" ] && continue

5
更准确地说,read 使用的定界符由 IFS 变量确定,默认为空格。只需取消设置 IFS 以恢复使用空格作为定界符即可。 - Arkku
2
更简单的方法是,如果您使用bash的[[语法,则无需引用行:[[ -z $line ]] && continue - pihentagy
3
@pihentagy 嗯,这个短语的字符数与原文相同,但是方括号 [] 在某些国际键盘上比引号更难打,而且它只能在 Bash 中使用。所以说这并不一定更简单,但可以作为一个替代方案。=) - Arkku
5
[ -z "$line" ] && continue 这一行本身就是可执行的。这个简洁的语句等同于 if [ -z "$line" ] ; then continue ; fi。另外,不要忘记在开头设置 IFS=" \t\n",除非您不想跳过制表符。 - Xin Cheng
针对建议添加内容的编辑,请以自己的回答为主 – 这样回答问题更加原汁原味,而且适用于各种不同的shell,所以我认为通过增加特定shell或超出原问题需要的其他情况来复杂化答案并没有起到改进的作用。 - Arkku

19

试试这个

while read line;
do 

    if [ "$line" != "" ]; then
        # Do something here
    fi

done < $SOURCE_FILE

1
有关方括号表示法的更多信息,请参阅test的man页面 - c0dem4gnetic
缺点在于:如果 if 语句中的部分很长,你会得到一段难以阅读的代码。因此,始终建议使用 continue 解决方案。 - Timo

7

bash:

if [[ ! $line =~ [^[:space:]] ]] ; then
  continue
fi

请使用done < file而不是cat file | while,除非你知道为什么要使用后者。


我需要一些东西在bash和sh中都能正常工作。如果未安装bash,是否有使用sh/sed/tr的解决方案? - planetp
1
这个有效,另一个([ -z "$line" ] && continue)无效。我想知道为什么。 - Timo

2

while read循环中,如果你想要跳过空行或者至少包含一个空格的行,那么cat在这种情况下是无用的。

i=0
while read -r line
do
  ((i++)) # or $(echo $i+1|bc) with sh
  case "$line" in
    "") echo "blank line at line: $i ";;
    *" "*) echo "line with blanks at $i";;
    *[[:blank:]]*) echo "line with blanks at $i";;
  esac
done <"file"

1
if ! grep -q '[^[:space:]]' ; then
  continue
fi

0
awk 'NF' file | while read line
do
    # run some commands using $line    
done

从类似的问题中窃取了这个答案: 使用sed删除空行


0
blank=`tail -1 <file-location>`
if [ -z "$blank"  ]
then
echo "end of the line is the blank line"
else
echo "their is something in last line"
fi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接