我正在嘗試在特定行上的另一個變數文字之後插入變數文字。以下是迄今為止我的嘗試,據我所知,如果我可以轉義引號,以便awk
可以看到變量並仍然應用該變量,那麼它應該可以工作,但我不知道該怎麼做:
#!/bin/sh
VAR=$(head -n1 ~/Scripts/tmp/file.txt)
VAR1=$(head -n1 ~/Scripts/tmp/file1.txt)
awk '/$VAR/ { print; print "$VAR1"; next }1' ~/Scripts/tmp/file.txt
答案1
若要將字串傳遞給 awk 腳本,請透過環境變數傳遞它們。
export VAR VAR1
awk '
1
$0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt
我重新組織了你的腳本以使邏輯更簡單。我還用字串比較替換了正則表達式匹配:使用正則表達式匹配,$VAR
將被視為正則表達式,它不會執行字串比較。甚至/$VAR/
不會使用您需要的值VAR
(這是 Perl 語法,而不是 awk)match($0, VAR)
。
關於其他一些實際上不起作用的解決方案的註解(僅當變數不包含任何特殊字元時它們才起作用,哪個字元是特殊字元取決於方法):
awk -v awkvar="$VAR" '$0 == awkvar …'
展開行內容中的反斜線。awk "/$VAR/" …
使 shell 將 的值擴展VAR
為 awk 片段。例如,如果file.txt
包含則執行^/ {system("touch ~/naughty")} /
該命令。touch ~/naughty
另一種方法是讓 awk 讀取所有檔案。
awk '
BEGIN { VAR1 = getline <"~/Scripts/tmp/file1.txt"; }
NR == 1 {VAR = $0}
1
$0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt
答案2
一種可能的 AWK 解決方案:
awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'
打破所有外部變數周圍的 ' 引號。
像另一篇文章建議的傳遞變數的另一個可能的解決方案是將 VAR1 作為 awk 變數傳遞,但我認為您仍然需要使用 VAR 對模式進行單引號區塊轉義:
awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'
您可以嘗試使用 sed :) 它是專門為這種替換而設計的。
sed "s/$VAR.*/\0\n$VAR1/" ~/Scripts/tmp/file.txt
如果您可以在一行上有多個 VAR 實例,則在 sed 命令末尾添加 g (全域),這樣它就不會在找到的第一個匹配處停止:
sed "s/$VAR.*/\0 $VAR1/g" ~/Scripts/tmp/file.txt
重要! ; '例如:
sed "s;$VAR.*;\0\n$VAR1;" ~/Scripts/tmp/file.txt
sed 命令的解釋:
我們在 sed 命令周圍使用雙引號"而不是單引號,這樣像 VAR 和 VAR1 這樣的變數將被它們的值替換。這發生在 sed 執行命令之前,這就是為什麼如果 / 可以出現在您需要尋址的變數內容中(對於awk 也是如此)
's' 表示您編寫以下形式的替換命令:
s/<pattern>/<replacement pattern>/
'/緊跟在s 之後的分隔符號將用於分隔指令的各個部分,因此如果您放置; ,則必須像上面所示那樣使用; 來匹配$VAR 變數的內容。內容。
哎呀沒有看到關於下面的行的部分..固定模式。
答案3
如果你想使用awk
,你必須使用選項傳遞bash
變數: awk
-v
awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt
但請檢查 Rob 的答案以獲得更正確和詳細的解決方案。