Bash
在第一個匹配的括號之間列印內容
輸入範例:
START{ some text { more text} almost there } nothing important{ ...
期望的輸出:
START{ some text { more text} almost there }
第一個開括號可以在不同的位置:
START{... START {... START {...
開始還可以包含特殊字元,例如:*
我想列印出所有內容,包括從 START 開始的所有內容以及第一次匹配之間的所有內容
{}
(在 bash 中)。我正在考慮有一個計數器,它在找到{
時增加,在找到時減少}
。當結果為零時,它會停止列印(大括號總是匹配的)。
與
pcregrep
:start_word='START' pcregrep -Mo "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" < your-file
使用
zsh
內置函式:set -o rematchpcre start_word='START' [[ $(<your-file) =~ "(?s)\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})" ]] && print -r -- $MATCH
那些使用 PCRE 的遞歸正則表達式功能,
(?1)
上面呼叫了第一(...)
對中的正則表達式。如果你既沒有
pcregrep
也沒有zsh
,你總是可以求助於真實的東西(PCRE中perl
的):P
perl -l -0777 -sne ' print $& if /\Q$start_word\E\h*(\{(?:[^{}]++|(?1))*+\})/s ' -- -start_word='START' < your-file
(請注意,除
perl
一個之外的所有內容都假定$start_word
不包含\E
)。
一種簡單的蠻力方法,可以在所有 Unix 機器上的任何 shell 中的任何 awk 中工作:
$ cat tst.awk s=index($0,"START") { $0=substr($0,s); f=1 } f { rec = rec $0 RS } END { len = length(rec) for (i=1; i<=len; i++) { char = substr(rec,i,1) if ( char == "{" ) { ++cnt } else if ( char == "}" ) { if ( --cnt == 0 ) { print substr(rec,1,i) exit } } } }
$ awk -f tst.awk file START{ some text { more text} almost there }