[英]Delete all lines between two patterns (exclusive of the pattern) using sed or awk
[英]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.