当文件连续包含超过 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
此回复已编辑,原来漏掉了一个条件。