Grep

通過多個多行文本搜尋文本

  • August 19, 2021

我正在使用aplay -Lwhich 列出多個設備及其描述。

$ aplay -L
null
   Discard all samples (playback) or generate zero samples (capture)
pulse
   PulseAudio Sound Server
surround40:CARD=PCH,DEV=0
   HDA Intel PCH, ALC1220 Analog
   4.0 Surround output to Front and Rear speakers
hw:CARD=PCH,DEV=0
   HDA Intel PCH, ALC1220 Analog
   Direct hardware device without any conversions

其中null, hw:CARD=PCH,DEV=0,surround40:CARD=PCH,DEV=0是設備名稱。我想通過設備名稱和它的描述搜尋模式並找到與它的描述匹配的設備名稱。

我的期望是

aplay -L | pattern_match_command "Surround output"

將返回surround40:CARD=PCH,DEV=0 類似

aplay -L | pattern_match_command "pulse"

將返回pulse

基本上每個設備的上下文是

surround40:CARD=PCH,DEV=0
   HDA Intel PCH, ALC1220 Analog
   4.0 Surround output to Front and Rear speakers

目前我正在使用不包括描述的行處理。

aplay -L | grep "pulse"

任何提示我可以使用什麼工具。我在用ubuntu 18.04

使用具有 PCRE 支持的 GNU grep

mygrep() {
## helper  variables to make writing of regex tractable:-

## any nonwhitespace char which is not a colon
noncolon='(?:(?!:)\S)'
nonequal='(?:(?!=)\S)'

# these occur in the description line after the colon, akin to key=value pairs
pair="${nonequal}+=${nonequal}+"

# a header line comprises a run of noncolon nonwhitespace optionally followed by pairs
hdr="${noncolon}+(?::(?:,?${pair})+)?"

# description line is one that begins with a space and has atleast one nonwhitespace
descline='(?:\s.*\S.*\n)'

# supply your string to search for in the description section here ( case insensitive)
srch=$1
t=$(mktemp)

aplay -L | tee "$t" \
| grep -Pzo \
"(?im)^${hdr}\n(?=${descline}*\h.*\Q${srch}\E)" \
| tr -d '\0' \
| grep . ||
grep -iF -- "$1" "$t"
}

## now invoke mygrep with the search string
mygrep  'card=pch'

輸出:-

surround40:CARD=PCH,DEV=0
hw:CARD=PCH,DEV=0

使用awk

aplay -L |
pat='surround' awk '
   BEGIN { pat = tolower(ENVIRON["pat"]) }
   /^[^[:blank:]]/ { dev = $0; next }
   tolower($0) ~ pat { print dev }'

awk命令將記住變數中以非空白字元開頭的每一行dev。每當其他行與給定模式匹配時,dev就會輸出變數的值。

模式是通過環境變數傳入的,pat. 這被轉換為小寫並儲存在awk變數pat中。當模式匹配一​​行時,該行也被轉換為小寫,所以在這個意義上,模式匹配是不區分大小寫的。

根據您的範例數據,上述命令的輸出將是

surround40:CARD=PCH,DEV=0

由於匹配了surround該行中的單詞

4.0 Surround output to Front and Rear speakers

引用自:https://unix.stackexchange.com/questions/662768