如何比较 bash 中条件语句中的 grep 行号?

How can I compare grep line numbers in a conditional statement in bash?

我正在构建一个 git 预提交挂钩以拒绝包含字符串 'X' 的提交。我在下面有一个工作版本。

#!/bin/sh

RED='3[0;31m'
NC='3[0m'

for FILE in `git diff --cached --name-only --diff-filter=ACM`; do
    if [ "grep 'X' $FILE" ]
    then
    echo -e "${RED}[REJECTED]${NC}"
    exit 1
fi
done
exit

我想做的是更改条件以查找字符串 'X',如果找到,则在恰好 3 行后查找字符串 'Y'。例如,X 在第 7 行,Y 在第 10 行。我只想拒绝包含由 3 行分隔的字符串 'X' 和 'Y' 的文件的提交。我尝试了一些时髦的东西,比如:

if [ "grep -n 'X' $FILE" ] + 3 -eq [ "grep -n 'Y' $FILE" ]

如何创建我需要的条件?如何最好地概括这一点?

您可以使用grep -A提取X后面的三行,然后检查Y的最后一行:

#!/bin/bash
file=
chunk=$(grep -A3 X "$file")
size=$(wc -l <<< "$chunk")
lastline=${chunk##*$'\n'}

if ((size == 4)) && grep -q Y <<< "$lastline" ; then
    echo Found both X and Y
fi

文件末尾 Y 跟在 X 之后且中间少于两行的情况需要进行大小检查。

我可以成功,但可能有更简单的方法:

for FILE in `git diff --cached --name-only --diff-filter=ACM`; do
    nl $FILE | grep 'X' - | while read line blah; do
        lines=$( head -n $(( $line + 3 )) $FILE | tail -n 1 | grep 'Y' | wc -l )
        if [ $lines -gt 0 ]; then
            echo you got it baby, on line $line for file $FILE
        fi
    done
done

或者类似的东西。

使用 sed 检查第一个模式后 n 行出现的模式

sed -n '/<pattern1>/{n;n;n; /<patter2>/p}' $FILE