如何在文本/模式的前两个实例之间获取单词?

时间:2019-05-15 10:47:15

标签: linux bash awk sed grep

输入:

===================================
v2.0.0

Added feature 3
Added feature 4
===================================
v1.0.0

Added feature 1
Added feature 2
===================================

我想要的输出:

v2.0.0

Added feature 3
Added feature 4

我尝试了this,但是它得到的 first 等于(=),而 LAST 等于(=),而我想要得到的是前两个等于(=)

6 个答案:

答案 0 :(得分:3)

这是awk中的一个:

$ awk '/^=+$/{f=!f;if(f==1)next;else if(f==0)exit}f' file
v2.0.0

Added feature 3
Added feature 4

精美印刷:

$ awk '/^=+$/ {     # at ===...
    f=!f            # flag state is flipped
    if(f==1)        # if its one (first ===...)
        next        # next record
    else if(f==0)   # if zero (second ===...)
        exit        # nothing more to do yeah
}
f' file             # print

答案 1 :(得分:3)

这是GNU sed中的另一个:

$ sed -n '/^=\+$/,//{//!p;b};q' file
v2.0.0

Added feature 3
Added feature 4
  • /^=\+$/,///^=\+$/,/^=\+$/的简写,它选择包含等号的两行之间的行,并为这些行执行以下花括号之间的命令,
  • //!p/^=\+$/!p的简写,表示如果输入行不是仅由=组成的行之一,请打印出来,
  • b表示转到循环末尾(即通过q),
  • q用于在打印选定的行后退出sed。

以下版本可与 all 兼容POSIX的sed一起使用,但其神秘性提高了2倍:

sed -n -e '/^=\{1,\}$/,//{//!p;b' -e '}' -e 'q' file

请注意,如果输入中有两条相应的=行,那么这些行将不会起作用。

答案 2 :(得分:3)

请您也可以尝试以下方法。

awk '/^=/{count++;next} count>=2{exit} {print}'  Input_file

答案 3 :(得分:3)

使用GNU awk进行多字符RS:

$ awk -v RS='(^|\n)=+\n' 'NR==2' file
v2.0.0

Added feature 3
Added feature 4

与其他awk一样,它的长度会更长:

$ awk '
    /^=+$/ { prt(); next }
    { rec=rec $0 ORS }
    END { prt() }
    function prt() { if (++nr==2) printf "%s", rec; rec="" }
' file
v2.0.0

Added feature 3
Added feature 4

请注意,以上内容可用于打印任意数量的记录,而不仅仅是第二个记录,只需将2更改为要打印的任何记录号,就可以轻松添加/更改条件,例如仅打印包含某些记录的记录代替或基于记录号的字符串,例如如果它包含foo,则打印第17条记录:

awk -v RS='(^|\n)=+\n' 'NR==17 && /foo/' file

说明:您的记录用===行分隔,因此将记录分隔符RS设置为与该描述匹配的正则表达式,然后在记录数(NR )达到您想要的数字,即2(因为第一行===之前有一个空记录)。

答案 4 :(得分:1)

可以说,更干净的GNU sed解决方案:

sed -E '0,/^={35}$/d; //Q'

或者,如果您对其他答案中提出的更简单的正则表达式感到满意:

sed -E '0,/^=+$/d; //Q'

进一步的解释:

  • (扩展为音符-E)正则表达式/^={35}$/与一行一样匹配正好由35个等号组成的行。 (备用正则表达式/^=+$/匹配一个或多个等号的行。)

  • 命令0,/^={35}$/d选择从文件开头到模式的第一次出现的所有行,然后删除。

  • 表达式//导致sed正则表达式默认为用作地址或s///命令一部分的最后一个正则表达式。

  • Q命令是GNU扩展,导致sed退出而不进行打印。

对此进行测试:

# test.sh

cat > FILE <<EOF
other
text
===================================
v2.0.0

Added feature 3
Added feature 4
===================================
v1.0.0

Added feature 1
Added feature 2
===================================
EOF

gsed -E '0,/^={35}$/d; //Q' FILE

输出:

▶ bash test.sh 
v2.0.0

Added feature 3
Added feature 4

答案 5 :(得分:1)

这可能对您有用(GNU sed):

sed -n '/^=\+$/{:a;n;//q;p;ba}' file

通过设置选项-n使用显式打印,这意味着将仅通过pP命令来打印行。

遇到包含所有=字符的行时,获取下一行,如果该行包含相同的正则表达式,则退出文件。否则,打印当前行并重复。