簡體   English   中英

bash中的sed param替換

[英]sed param substitution in bash

“我是bash開發和使用sed的新手。我已經嘗試了幾天,並盡可能閱讀和搜索有關sed的書籍。

這是我的問題。 我需要在要替換的模式中用術語的“值”替換一行。 我在正則表達式中使用了反向引用,並且可以在模式內獲取術語以替換模式。 但想獲得該術語的“價值”。

以下是到目前為止我可以使用的代碼,但是無法完成最后一步。

1 #!/bin/bash
2 
3 val='<%= @test %> this is my <%= @new %> here'
4 echo "Echo: $val"
5 
6 export test='cool value'
7 export new='new value'
8 
9 echo $val | sed -e "s:\<\%\= \@\([A-Za-z0-0]*\) \%\>:\1:g"

為了便於理解“模式”,我在sed“ s”語句中使用了“:”作為分隔符。 我在Google上看到的一些帖子表明,要獲取反向參考詞的價值,我應該使用$ \\ 1,但這似乎行不通。

我正在尋找的輸出是:

“很酷的價值,這是我的新價值”

整個模式是我要替換的。 抱歉,我沒有像原來那樣明確。

以上只是測試,看我是否可以進行更換。 最終目的是能夠用配置文件中的環境變量(逐行)替換配置文件中的“ <%= @term%>”。

任何幫助,將不勝感激。

您添加了太多的斜杠。 添加它們不會使您更安全。 例如, \\<\\>具有特殊含義,分別代表單詞的開頭和結尾。

要實現這一點,它比您想象的要簡單得多:

sed -e "s/<%= @\([A-Za-z0-9]*\) %>/\1/g"

這應該能夠捕獲testnew

要管理sed,您也不需要閱讀太多內容。 本教程應該足夠了: http : //www.grymoire.com/Unix/sed.html

修訂問題的答案

sed不是正確的工具。 您可以運行腳本之前將shell變量的值替換為sed腳本。 但是,在sed腳本開始運行之后 ,sed無法動態查找shell變量的值。

Shell會做您想要的:

#!/bin/bash

val='<%= @test %> this is my <%= @new %> here'

test='cool value'
new='new value'

for var in test new
do
    val=${val//<%= @$var %>/${!var}}
done
echo $val

上面產生輸出:

cool value this is my new value here

除非有令人信服的理由使用shell變量,否則您可能要考慮使用bash關聯數組。 請參閱下面的示例,該示例適用於原始問題。

原始問題的答案

您想要的不是sed功能的理想選擇。 gawk可以訪問shell環境變量,並且可以使用它。 但是,使用bash的內置參數擴展功能來完成所需的操作相對簡單:

#!/bin/bash

val='<%= @test %> this is my <%= @new %> here'
echo "Echo: $val"

export test='cool value'
export new='new value'

val=${val//@test/$test}
val=${val//@new/$new}

echo $val

上面產生輸出:

Echo: <%= @test %> this is my <%= @new %> here
<%= cool value %> this is my <%= new value %> here

另類

如果有很多變量,如testnew ,則創建一個關聯數組來保存它們可能會更容易:

#!/bin/bash

val='<%= @test %> this is my <%= @new %> here'
echo "Echo: $val"

declare -A arr=([test]='cool value' [new]='new value')

for key in "${!arr[@]}"
do
    val=${val//@$key/${arr[$key]}}
done

echo $val

上面產生輸出:

Echo: <%= @test %> this is my <%= @new %> here
<%= cool value %> this is my <%= new value %> here

感謝@HuStmpHrr和@ John1024的幫助。 @HuStmpHrr對於斜杠的濫用是正確的……而@ John1024對於“ sed”不是該工作的正確工具這一事實似乎是正確的。

我發現“ perl”以我想要的方式工作(一位同事發現了這一點)。 我寧願不使用Perl(只是因為我寫了太多糟糕的 Perl代碼后就成為了反Perl的頑固者),但是我不知道如何使用環境變量來代替ENTIRE模式。

我想出了以下代碼來創建正確的輸出。 如果其他人能弄清楚如何用sed或awk做到這一點,我將不勝感激。

1 #!/bin/bash
2 
3 pat="<%= *@([a-zA-Z0-9_]*) *%>"
4 val='<%= @test %> this is my <%= @new %> here'
5 echo "Echo: $val"
6 
7 export test='cool value'
8 export new='new value'
9 
10 # this is the old attempt with sed. It didn't produce output I wanted
11  echo $val | sed -e 's/<%= @\([A-Za-z0-9]*\) %>/\1/g'
12 
13 # this works the way I want to with Perl
14  echo $val | perl -pe 's/<%= *@([a-zA-Z0-9_]*) *%>/$ENV{$1}/g'

感謝您指出正確方向的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM