使用 Bash 计算并显示空行数

使用 Bash 计算并显示空行数

当文件连续包含超过 21 个空行时,我们必须发送错误消息。空白可以包含空格。当我们切换到新服务器时,当前的解决方案停止工作。它可能从来没有工作过,但我的任务是确保各种脚本工作。该脚本是用 Bash 编写的,因此理想情况下,解决方案可以与 Bash 一起使用,否则,我必须在脚本内进行切换,我认为这将是一个问题。

错误消息还必须包含空行之前和之后的行。

这是之前使用的: grep 来计算问题数量(如果大于 0,它会发送一封电子邮件):

grep -nc $'[\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a]' filename

显示问题行(显示在电子邮件中)

grep -n $'[\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a]' filename

再说一遍,我不知道这是否有效。但是,我需要让它发挥作用。我尝试过使用这个,它适用于计数...但如果有空格,它就不起作用,而且我无法让前/后行使用它。

grep -czoP '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n' filename

答案1

使用awk脚本检测文件是否有超过一定数量的空行或仅包含空格(空格和/或制表符):

if ! awk -v max=21 '/^[[:blank:]]*$/ { if (++count >= max) exit 1; next } { count = 0 }'
then
    echo 'file contains 21 or more consecutive blank lines'
else
    echo 'file contains no more than consecutive 20 blank lines'
fi <file

这将依次将正则表达式^[[:blank:]]*$与输入文件中的每一行进行匹配。该表达式将匹配空行和仅包含空格和/或制表符的行。如果表达式匹配,则计数器递增。如果计数器达到给定的最大值(max在命令行上设置的变量),脚本将以非零退出状态终止。如果表达式不匹配,计数器将重置为零。

答案2

您可以使用正则表达式来搜索更复杂的匹配项。在您的情况下,您需要在接受任意数量(0 或更多)空白字符的每一行中添加(我将其截断为三行而不是 21 行):

grep -czP '[ ]*\n[ ]*\n[ ]*\n' filename

答案3

回到你的问题,我同意awk更适合这项任务。这里有一个awk脚本,用于打印这些空行之前和之后的行:

awk 'BEGIN{AA="";BB="";CC=0}{LST=CC;if(CC==0){BB=AA};AA=$0;if($0 ~ "^[[:space:]]*$"){CC++}else{CC=0;if(LST>21){print "Error:\n"BB"\n"LST" free, to:\n"AA"\n\n"}}}' searched.txt 

您可以将 awk 的命令保存在文件中,这有助于调试。这样的文件可能看起来像:

BEGIN{AA="";BB="";CC=0}
{ LST=CC;if(CC==0){BB=AA};AA=$0;
  if( $0 ~ "^[[:space:]]*$") { CC++ } 
  else { CC=0; 
         if(LST>21) {print "Error:\n"BB"\n"LST" free, to:\n"AA"\n"}};
} 

bash 命令应该是:

awk -f command.file searched.txt

这是一个例子,假设空格前后至少存在一行。您可以针对searched.txt除空白行(带空格)之外不包含其他行的情况调整此示例。或者searched.txt以超过 21 个空行开始或以超过 21 个空行结束。

答案4

while read -r line; do
    # add +1 every time the line is empty, reset the count if line contains anything
    [[ -z $line ]] && i=$((i+1)) || i=0

    if [[ $i -ge 20 ]]; then
        # Do the error handeling in this block
        echo "ERROR: 20+ empty consecutive lines"
        break # stop reading file by breaking the loop
    fi
done <file

此回复已编辑,原来漏掉了一个条件。

相关内容