特定の文字列を一致させた後にのみファイル内にタイムスタンプを追加したいと思います。
タイムスタンプ形式:03_2016
ファイルには「$channel_name ポリシー「文字列、この文字列を次のように置き換えたいと思います。」$channel_nameポリシー_03_2016」
ファイルの内容にタイムスタンプを追加したいです。
package_path=/LSB/Packages/Policy
channel_path=/LSB/Channels/$parent_channel_name/$channel_name Policy
erratum_path=/LSB/Errata/$erratum_type Policies/$erratum_name
errata_path =/LSB/Errata/$parent_channel_name/$channel_name Advisory Roll-Up Policy
package_path=/LSB/Packages/Unapproved/$channel_name
必須ファイル形式:
package_path=/LSB/Packages/Policy
channel_path=/LSB/Channels/$parent_channel_name/$channel_name Policy_03_2016
erratum_path=/LSB/Errata/$erratum_type Policies/$erratum_name
errata_path =/LSB/Errata/$parent_channel_name/$channel_name Advisory Roll-Up Policy
package_path=/LSB/Packages/Unapproved/$channel_name
次に、次のコマンドを使用してファイルにタイムスタンプを追加します。
sed -i "s/$channel_name Policy/$channel_name Policy_$(date +%m_%Y)/g" filename
ただし、このコマンドは次の項目をすべて置き換えます。ポリシーそしてポリシー_03_2016 このように:
package_path=/LSB/Packages/Policy_03_2016
channel_path=/LSB/Channels/$parent_channel_name/$channel_name Policy_03_2016
erratum_path=/LSB/Errata/$erratum_type Policies/$erratum_name
errata_path =/LSB/Errata/$parent_channel_name/$channel_name Advisory Roll-Up Policy_03_2016
package_path=/LSB/Packages/Unapproved/$channel_name
この問題に対する解決策はありますか?
答え1
$
パラメータ拡張(例:$var
、、、)、算術拡張(例)、$1
およびコマンド置換(例:$channel_name
$((1+1))
$(cmd)
はい実際にここで使用されます)。
$
また、/ を使用して有効にしない限り、s/regex/replacement/
sed
「トピックの終わり」を意味する演算子であるため、正規表現(コマンドの左など)の特殊機能です。-E
-r
拡大する$
正規表現自体の終わりまたは後ろ\)
(またはサポートされている場合)を除いて、特別ではない正規表現です\|
。それでもそれから逃げるのは良い習慣です。
sed
シェルと二重引用符内の正規表現は、\
文字の特別な意味を排除するエスケープ演算子をサポートします。\
どちらの場合も、自分で脱出することも可能です。
ここでは、次のようにすることができます。
sed -i "s/\\\$channel_name Policy/\$channel_name Policy_$(date +%m_%Y)/g" filename
つまり\\\$
、脱出する \
再び脱出する場所に渡されるためにそれ自体と\$
シェル 。コマンドの代替部分が特別ではないので、右であれば十分です。\$
sed
\
$
\$
$
s/regexp/replacement/
POSIXではありませんが、これは私が知っているすべてのシェルでも機能します。
sed -i "s/[$]channel_name Policy/&_$(date +%m_%Y)/g" filename
[$]
もう一つの方法です脱出する $
正規表現で。[...]
マッチ置く1つだけを含む文字:$
。 POSIXはシェルを指定しませんが、[$]
そのまま保持されないシェルはありません。ただし、[\$]
POSIX 準拠にはシェルコードが必要です。
また、&
これに代わって表現するために使用します。正規表現に一致する文字列。
別のオプションは、次のものを使用することです。アポストロフィ(特別ではない)ほとんどの文字列と$
コマンドの置き換え$
では必ずしも必要ではありませんが、二重引用符は正規表現からまだエスケープされます。
sed -i 's/\$channel_name Policy/&_'"$(date +%m_%Y)/g" filename
二重引用符を使用する必要があります$(...)
。それ以外の場合は、分割+グローブが適用されます。
答え2
「don_crissti」が述べたように、ドル記号をエスケープする必要があります。それ以外の場合は、変数の内容を取得しようとします(あなたの場合はnull)。
あるいは、ファイルにもスラッシュがあるので、「/」以外の区切り文字を使用する方が安全です。ただし、代替式で使用しない限り、これは問題ではありません。
私の作業ソリューション:
sed -i 's!\$channel_name Policy!&_'$(date +%m_%Y)'!g' policies.txt
&
2番目に可能な改善方法は、検索された式といくつかの追加コンテンツが正確に一致するため、代替項目にを使用することです。
第三に、私のテストでは、コマンドが式の$(date +%m_%Y)
外にあるときにのみsed
(二重引用符で囲まれて)動作するようにすることができました。
GNU sed
私も(上記の行)とwithを試しましたが、OSX sed
どちらも正しく解釈できませんでした$(command)
。