簡體   English   中英

Awk或Sed:返回相同模式的兩個實例之間的行

[英]Awk or Sed: Return lines between two instances of the same pattern

我有一個看起來像這樣的文本文件:

-+- beginning text
hey there
hi there
ho there
-+- ending text
other stuff
that is
immaterial for
my purposes

我只想抓住 - + - 模式之間的界限,所以它會返回:

hey there
hi there
ho there

標准awk方式:

awk '/beginning text/ {flag=1;next} /ending text/ {flag=0} flag {print}'

只要“開始文本”和“結束文本”是不同的模式,效果很好。

唉,對於我的需要,“開始文本”和“結束文本”可以改變。 這兩行中唯一一致的部分是“ - + - ”。 文件中的所有其余文本可以完全不同; 我不能依賴任何一致的模式。 唯一可靠的文字是 - + - 。 當兩個字符串相同時,awk失敗。

關於如何返回相同模式的兩個離散實例之間的線條的任何想法,不包括包含模式的線條? 不必是awk,只需要在bash shell腳本中工作。

如果圖案相同並且您不希望打印出圖案線,則只需在每次看到圖案時通過反轉標記來組合這兩個圖案。

awk '/^-\+-/ {flag=!flag; next} flag {print}'
cat ttt
aaaa
bbbb
ccccc
bbbb
xxxxx
gggg
awk '/bbb/ {flag=1-flag; next} {if (flag) {print $0}}' ttt
ccccc

使用sed

sed -n '/^-+-/,/^-+-/ { /^-+-/! p; }'

使用awk

awk '/^-\+-/ { flag++; next } flag % 2'

使用perl

perl -ne 'if (/^-\+-/) { $a ^= 1; next } print if $a'

使用new(ish) perl

perl -ne 'print if /^-\+-/.../^-\+-/ and !/^-\+-/'

使用bash

#! /bin/bash
while IFS= read -r line; do
    if [[ $line =~ ^-\+- ]]; then
        let flag^=1
        continue
    fi
    if [ $flag -ne 0 ]; then
        printf '%s\n' "$line"
    fi
done

輸出:

hey there
hi there
ho there

用於通用用途(相同或不同的啟動/停止模式)

awk '#     Start pattern
     $0 ~ /^-\+-/ {flag=1;next}
     #     Stop   pattern
     $0 ~ /^-\+-/ {flag=0;next}

     flag { print}
    ' YourFile

注意: +需要在正則表達式中進行轉義以供臨時使用

根據@fedorqui的評論改編

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM