Bash
在 shell 腳本中提取子字元串“mode:”之後的數值的簡潔但易讀的方法
我有這個字元串:
DMT mode 4: 640x480 @ 60Hz 4:3, clock:25MHz progressive
我想從中提取模式編號(第一個 : 之前的部分),在此範例中為 4。正如您可能期望的那樣,模式編號可能是 1 或 2 位數字,並且不能依賴它之前的文本在完全相同的字元長度上。
我有一個可行的解決方案:
$picked = "DMT mode 4: 640x480 @ 60Hz 4:3, clock:25MHz progressive" echo $picked | awk -F"mode " '{print $2}' | tr : '\n' | head -n1
但我覺得必須有一種更優雅的方式來做到這一點。現在優雅且易於學習,以後再閱讀(因此,可能不涉及正則表達式)。我的夢想命令是這樣的:echo $picked | 在“模式”之間:“
這裡還有一些範例來顯示需要可解析的輸入範圍:
CEA mode 7: 720x480 @ 60Hz 16:9, clock:27MHz x2 interlaced CEA (native) mode 16: 1920x1080 @ 60Hz 16:9, clock:148MHz progressive DMT mode 58: 1680x1050 @ 60Hz 16:10, clock:146MHz progressive
正則表達式將是更直接的解決方案:一些選項:
echo "$picked" | grep -oP '(?<=mode )\d+' echo "$picked" | grep -oP '(?<=mode )[[:digit:]]+'
如果您不喜歡 PCRE 功能:
echo "$picked" | grep -oE 'mode [[:digit:]]+' | tr -d 'mode '
該
tr
命令不會刪除單詞“mode”,而是刪除所有字元“m”、“o”、“d”、“e”、“”。如果你真的喜歡awk,遍歷單詞直到你點擊“mode”
echo "$picked" | awk '{for (i=1; i<NF; i++) if ($i == "mode") {print $(i+1); exit}}' | tr -d :
由於您已經在 shell 變數中包含了字元串,那麼如何替換 bash 參數:
tmp=${picked#*mode } # remove up to "mode " value=${tmp%%:*} # remove the colon and everything after
然後
$ declare -p picked tmp value declare -- picked="DMT mode 4: 640x480 @ 60Hz 4:3, clock:25MHz progressive" declare -- tmp="4: 640x480 @ 60Hz 4:3, clock:25MHz progressive" declare -- value="4"
參考手冊中的3.5.3 Shell Parameter Expansion(並忽略一些更精細的點):
${var#pattern}
刪除匹配模式的最短前綴${var##pattern}
刪除匹配模式的最長前綴${var%pattern}
刪除匹配模式的最短後綴${var%%pattern}
刪除匹配模式的最長後綴“最短”和“最長”之間的區別是關鍵。請注意,給定的字元串在後綴中包含多個冒號—— using
${tmp%:*}
only 刪除最後一個冒號和後面的字元。