使用 bash 我如何找到一個字串并更新它旁邊的字串,例如傳遞值
my.site.com|test2.spin:80
proxy_pass.map
my.site2.com test2.spin:80
my.site.com test.spin:8080;
預期的輸出是更新proxy_pass.map與
my.site2.com test2.spin:80
my.site.com test2.spin:80;
我嘗試使用 awk
awk '{gsub(/^my\.site\.com\s [A-Za-z0-9] \.spin:8080;$/,"my.site2.comtest2.spin:80"); print}' proxy_pass.map
但似乎不起作用。有沒有更好的方法來解決這個問題。?
uj5u.com熱心網友回復:
使用您顯示的示例和嘗試,請嘗試以下awk代碼。var創建命名為在其中存盤值的shell 變數my.site.com|test2.spin:80。這進一步被傳遞給awk程式。在awk程式中創建名為的變數var1,其中包含 shell 變數 var 的值。
在BEGIN使用函式將(shell 變數的值容器)的值拆分awk為名為 arr 的陣列中,分隔符為. 其中是由 split 函式分隔的值的總數。然后使用回圈運行直到它創建以當前值索引命名的陣列并將 i 1 作為其值(基本上 1 是陣列的鍵,下一項是陣列的值)。splitvar|numfornumarr2i
在awk程式檢查條件的主塊中,如果$1在 arr2 中,則列印 arr2 的值,否則根據要求列印 $2 值。
##Shell variable named var is being created here...
var="my.site.com|test2.spin:80"
awk -v var1="$var" '
BEGIN{
num=split(var1,arr,"|")
for(i=1;i<=num;i =2){
arr2[arr[i]]=arr[i 1]
}
}
{
print $1,(($1 in arr2)?arr2[$1]:$2)
}
' Input_file
或者,如果您想 在第 1 和第 2 欄位之間保留空格,請嘗試以下代碼對上述代碼進行小調整。僅使用您展示的樣本進行撰寫和測驗。
awk -v var1="$var" '
BEGIN{
num=split(var1,arr,"|")
for(i=1;i<=num;i =2){
arr2[arr[i]]=arr[i 1]
}
}
{
match($0,/[[:space:]] /)
print $1 substr($0,RSTART,RLENGTH) (($1 in arr2)?arr2[$1]:$2)
}
' Input_file
注意:這個程式可以|在 shell 變數中使用多個值來傳遞和檢查awk程式中的值。但它認為它將是key|value|key|value...唯一的格式。
uj5u.com熱心網友回復:
如果列之間的空格數不顯著,一個簡單的
proxyf=proxy_pass.map
tmpf=$$.txt
awk '$1 == "my.site.com" { $2 = "test2.spin:80;" } {print}' <$proxyf >$tmpf && mv $tmpf $proxyf
應該做。如果您需要將列很好地排列,您可以將 替換print為合適的printf ....陳述句。
uj5u.com熱心網友回復:
#!/bin/sh -x
f1=$(echo "my.site.com|test2.spin:80" | cut -d'|' -f1)
f2=$(echo "my.site.com|test2.spin:80" | cut -d'|' -f2)
echo "${f1}%${f2};" >> proxy_pass.map
tr '%' '\t' < proxy_pass.map >> p1
cat > ed1 <<EOF
$
-1
d
wq
EOF
ed -s p1 < ed1
mv -v p1 proxy_pass.map
rm -v ed1
uj5u.com熱心網友回復:
一個awk想法,假設需要保持間距:
awk -v rep='my.site.com|test2.spin:80' '
BEGIN { split(rep,a,"|") # split "rep" variable and store in
site[a[1]]=a[2] # associative array
}
$1 in site { line=$0 # if 1st field is in site[] array then make copy of current line
match(line,$1) # find where 1st field starts (in case 1st field does not start in column #1)
newline=substr(line,1,RSTART RLENGTH-1) # save current line up through matching 1st field
line=substr(line,RSTART RLENGTH) # strip off 1st field
match(line,/[^[:space:];] /) # look for string that does not contain spaces or ";" and perform replacement, making sure to save everything after the match (";" in this case)
newline=newline substr(line,1,RSTART-1) site[$1] substr(line,RSTART RLENGTH)
$0=newline # replace current line with newline
}
1 # print current line
' proxy_pass.map
這會產生:
my.site2.com test2.spin:80
my.site.com test2.spin:80;
如果輸入看起來像:
$ cat proxy_pass.map
my.site2.com test2.spin:80
my.site.com test.spin:8080;
該awk腳本生成:
my.site2.com test2.spin:80
my.site.com test2.spin:80;
筆記:
- 如果需要執行多個替換,我建議將它們放在一個檔案中并
awk首先處理所述檔案 - 第二個
match()是根據 OP 的示例進行硬編碼的;根據實際檔案內容,可能需要擴展第二個中使用的正則運算式match() - 一旦對結果感到滿意,可以通過幾種方式更新原始輸入檔案... a)如果使用
GNU awkthenawk -i inplace -v rep....或 b)將結果保存到臨時檔案,然后mv將臨時檔案保存到proxy_pass.map
uj5u.com熱心網友回復:
這可能對您有用(GNU sed):
<<<'my.site.com|test2.spin:80' sed -E 's#\.#\\.#g;s#^(\S )\|(\S )#/^\1\\b/s/\\S /\2/2#' |
sed -Ef - file
從輸入引數構建一個 sed 腳本并將其應用于輸入檔案。
首先準備輸入引數,以便它們的元字符(在這種情況下,.'s 被轉義。
然后第一個引數用于準備匹配命令,第二個引數用作替換命令中要替換的值。
結果通過管道傳送到第二個 sed 呼叫中,該呼叫采用 sed 腳本并將其應用于輸入檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/520103.html
標籤:重击awksed
上一篇:如何將多個值插入json檔案?
