Shell

將 shell 變數作為 /pattern/ 傳遞給 awk

  • October 6, 2019

在我的 shell 函式之一中具有以下內容:

function _process () {
 awk -v l="$line" '
 BEGIN {p=0}
 /'"$1"'/ {p=1}
 END{ if(p) print l >> "outfile.txt" }
 '
}

,所以當呼叫 as 時_process $arg$arg被傳遞為$1,並用作搜尋模式。它以這種方式工作,因為 shell 擴展$1代替了 awk 模式!也l可以在 awk 程序中使用,用-v l="$line". 一切都好。

是否可以以相同的方式將模式作為變數進行搜尋?

以下將不起作用,

awk -v l="$line" -v search="$pattern" '
 BEGIN {p=0}
 /search/ {p=1}
 END{ if(p) print l >> "outfile.txt" }
 '

, 因為 awk 不會解釋/search/為變數,而是字面意思。

使用 awk 的~運算符,您不需要在右側提供文字正則表達式:

function _process () {
   awk -v l="$line" -v pattern="$1" '
       $0 ~ pattern {p=1} 
       END {if(p) print l >> "outfile.txt"}
   '  
}

雖然這會更有效(不必閱讀整個文件)

function _process () {
   grep -q "$1" && echo "$line"
}

根據圖案,可能需要grep -Eq "$1"

awk  -v pattern="$1" '$0 ~ pattern'

有一個awk問題\n是在. 因此,如果包含正則表達式中常見的反斜杠字元就會成為一個問題(對於 GNU 4.2 或更高版本,以 開頭和結尾的值也是一個問題)。不受該問題影響的另一種方法是編寫它:\f``\\``$1``$1``awk@/``/

PATTERN=$1 awk '$0 ~ ENVIRON["PATTERN"]'

它將有多糟糕將取決於awk實施。

$ nawk -v 'a=\.' 'BEGIN {print a}'
.
$ mawk -v 'a=\.' 'BEGIN {print a}'
\.
$ gawk -v 'a=\.' 'BEGIN {print a}'
gawk: warning: escape sequence `\.' treated as plain `.'
.
$ gawk5.0.1 -v 'a=@/foo/' BEGIN {print a}'
foo

awk但是,對於有效的轉義序列,所有s 的工作方式相同:

$ a='\\-\b' awk 'BEGIN {print ENVIRON["a"]}' | od -tc
0000000   \   \   -   \   b  \n
0000006

$a按原樣傳遞的內容)

$ awk -v a='\\-\b' 'BEGIN {print a}' | od -tc
0000000   \   -  \b  \n
0000004

\\更改為\\b更改為退格字元)。

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