从文件中捕获序列的开头

时间:2012-07-10 12:37:29

标签: bash sed awk grep

我有一个文本文件,如下所示:

      125
      126
      127    {
      566
      567
      568
      569       # blah blah
      570    {  #blah blah
      700
      701    {

数字是左对齐的,模式在增加的意义上总是相同,最后是花括号。我只需要捕获起始数字。大括号总是被找到并限于序列结束。该文件的显示如'125'所示。

总之我需要:

      125
      566
      700

我想出了什么:

      grep -A1 '{' | grep -v '{' | grep -oE '(^[0-9]+?)'

但这省略'125',但我通过在头部添加换行并插入{来克服。

我希望将其减少为单个正则表达式。

欢迎提出建议和更好的算法

6 个答案:

答案 0 :(得分:4)

awk 'BEGIN {p=1} p==1 {print $1;p=0} $0~/{/ {p=1}'

Output:
125
566
700

根据上面的文件格式,您可以使用awk和变量/标记来查找开头时{

答案 1 :(得分:3)

sed -n '1p;/{/{
N
s/.*\n\([0-9]\+\).*/\1/p
}' input_file

答案 2 :(得分:2)

您可能需要调整正则表达式,但是:

awk '!k; { k = !/^ *[0-9]* *{/ }'

这将打印第一行以及与正则表达式^ *[0-9]* *{匹配的行后面的任何行 你可以简化一些事情并做到:

awk '!k;{k=$2!="{"}'

这将打印第一行以及第二行是单个开括号的行后面的任何行。

答案 3 :(得分:1)

我会使用awk和一个标志来捕捉大括号的存在并打印下一行。在开头设置标志,你将获得第一行。

未经测试,但类似:

BEGIN {hasCurly = 1}
{ 
    if(hasCurly) 
        print $1;

    hasCurly = match($2,"^\{");
}

答案 4 :(得分:1)

这是一个纯粹的bash解决方案:

start=1
while read n rest; do
    if (( start )); then
        printf '%d\n' $n
        start=0
    elif [[ $rest = \{* ]]; then
        start=1
    fi
done < input

答案 5 :(得分:1)

sed将赢得代码高尔夫比赛=):

sed -n '1p;/{/{n;p}' file

删除号码后删除所有内容:

sed -n '1{s/\s*\([0-9]\+\).*/\1/;p};/{/{n;s/\s*\([0-9]\+\).*/\1/;p}' file