1. 程式人生 > 其它 >grep/awk/sed 的正則表示式,如何只把匹配的內容(不是整個匹配行)提取出來,儲存到 shell 指令碼變數

grep/awk/sed 的正則表示式,如何只把匹配的內容(不是整個匹配行)提取出來,儲存到 shell 指令碼變數

問題 1

描述

bash 指令碼中,需要把引數 -J -I 1 -M1 -a1 -x1 中的 -I x 引數提取出來,儲存備用。

確定正則表示式

-I 後面可以有一個空格,也可以沒有,空格之後只能是 01,正則表示式很容易寫出來 -I ?[01]

僅提取匹配內容,而非整行

可以通過 grep-o 引數實現

測試

echo "-J -I0 -M1 -a1 -x1" | grep -oE '\-I ?[01]'   # 輸出 -I0
echo "-J -I 1 -M1 -a1 -x1" | grep -oE '\-I ?[01]'  # 輸出 -I 1
echo "-J -I 2 -M1 -a1 -x1" | grep -oE '\-I ?[01]'  # 輸出為空
echo "-J -M1 -a1 -x1" | grep -oE '\-I ?[01]'       # 輸出為空

問題 2

描述

解決了正則匹配的問題,新的問題又來了。
指令碼內的函式呼叫有兩種方法:通過函式名 foo 直接呼叫,或者通過 $(foo) 呼叫。
注意:加不加 $() 是有差別的!具體差別如下:

#!/bin/bash

GLOBAL_VAR="Initial Value"

function foo()
{
   GLOBAL_VAR=$(echo "-J -I 1 -M1 -a1 -x1" | grep -oE '\-I ?[01]')
   echo "Hello World"
}

$(foo) # 新建子 shell 程序執行函式,在子 shell 程序中改變 GLOBAL_VAR 不影響當前 shell 的變數,foo 輸出(echo)的內容 Hello World 作為新的命令執行
echo $GLOBAL_VAR # 仍然輸出"Initial Value"

foo # 在當前 shell 程序中執行函式,改變 GLOBAL_VAR
echo $GLOBAL_VAR # 輸出"-I 1"

var1=$(foo) # 呼叫函式 foo,foo 的輸出(echo)儲存到變數 var1 中,var1 內容為 "Hello World"
var2=foo # var2 內容為 "foo"
var3=${foo} # 把變數 foo 的內容(因為沒有定義 foo 變數,foo 變數的內容自然為空)儲存到 var3 變數

echo "var1: $var1" # 輸出 Hello World
echo "var2: $var2" # 輸出 foo
echo "var3: $var3" # 無輸出

注意!即使在 $(foo) 函式中 exportGLOBAL_VAR 也是不行的。因為環境變數也是隻能在當前 shell 和子 shell 程序中生效,無法在父 shell 程序中訪問。