Bash,两行之间使用指定字符串进行grep

时间:2014-03-06 10:12:49

标签: regex bash grep

示例:

a43
test1
abc
cvb
bnm
test2
kfo

我需要test1和test2之间的所有行。在这种情况下,正常的grep不起作用。你有什么建议吗?

7 个答案:

答案 0 :(得分:50)

她有些awk 这些内容将从test1打印到test2

awk '/test1/{f=1} /test2/{f=0;print} f'
awk '/test1/{f=1} f; /test2/{f=0}' 
awk '/test1/,/test2/'

test1
abc
cvb
bnm
test2

这些会在test1test2

之间打印数据
awk '/test1/{f=1;next} /test2/{f=0} f' 
awk '/test2/{f=0} f; /test1/{f=1}' 

abc
cvb
bnm

答案 1 :(得分:41)

您可以使用sed

sed -n '/test1/,/test2/p' filename

要排除包含test1test2的行,请说:

sed -n '/test1/,/test2/{/test1/b;/test2/b;p}' filename

答案 2 :(得分:9)

如果你只能使用grep:

grep -A100000 test1 file.txt | grep -B100000 test2 > new.txt

grep -A然后一个数字获取匹配字符串后的行,grep -B获取匹配字符串之前的行。在这种情况下,数字100000必须足够大,以包括前后的所有行。

如果您不想包含test1和test2,那么之后可以通过grep -v删除它们,它会打印除匹配行之外的所有内容:

egrep -v "test1|test2" new.txt > newer.txt

或一行中的所有内容:

grep -A100000 test1 file.txt | grep -B100000 test2 | egrep -v "test1|test2" > new.txt 

答案 3 :(得分:6)

是的,正常的grep不会这样做。但是使用-P参数的grep将完成这项工作。

$ grep -ozP '(?s)test1\n\K.*?(?=\ntest2)' file
abc
cvb
bnm

\K会丢弃以前匹配的字符,在最后一次打印时,正向前方(?=\ntest2)断言匹配必须后跟一个\n换行符然后test2字符串。

答案 4 :(得分:0)

以下脚本包含了此过程。更多详情in this similar StackOverflow post

get_text.sh

function show_help()
{
  HELP=$(doMain $0 HELP)
  echo "$HELP"
  exit;
}

function doMain()
{
  if [ "$1" == "help" ]
  then
    show_help
  fi
  if [ -z "$1" ]
  then
    show_help
  fi
  if [ -z "$2" ]
  then
    show_help
  fi

  FILENAME=$1
  if [ ! -f $FILENAME ]; then
      echo "File not found: $FILENAME"
      exit;
  fi

  if [ -z "$3" ]
  then
    START_TAG=$2_START
    END_TAG=$2_END
  else
    START_TAG=$2
    END_TAG=$3
  fi

  CMD="cat $FILENAME | awk '/$START_TAG/{f=1;next} /$END_TAG/{f=0} f'"
  eval $CMD
}

function help_txt()
{
HELP_START
  get_text.sh: extracts lines in a file between two tags

  usage: FILENAME {TAG_PREFIX|START_TAG} {END_TAG}

  examples:
    get_text.sh 1.txt AA     => extracts lines in file 1.txt between AA_START and AA_END
    get_text.sh 1.txt AA BB  => extracts lines in file 1.txt between AA and BB
HELP_END
}

doMain $*

答案 5 :(得分:0)

你也可以这样做。让我们说这个文件test.txt的内容:

a43
test1
abc
cvb
bnm
test2
kfo

你可以做到

cat test.txt | grep -A10 test1 | grep -B10 test2

其中-A<n>是您在匹配文件后获得n行,-B<n>是在匹配前为您提供n行。您只需要确保n > number of expected lines between test1 and test2。或者你可以给它足够大以达到EOF。

结果:

test1
abc
cvb
bnm
test2

答案 6 :(得分:0)

PratPor的回答如上:

cat test.txt | grep -A10 test1 | grep -B10 test2

很酷..但如果您不知道文件长度:

cat test.txt | grep -A1000 test1 | grep -B1000 test2

不确定,但不是太糟糕。任何人都有更好的(更确定性)?