次のようないくつかのプレースホルダーを持つLinuxシステムにはいくつかのファイルがあります。
テスト.txt:
This is a line with <VARIABLE1>@<VARIABLE2>.
This is a line with <VARIABLE3>.
This is a line with <VARIABLE_UNKNOWN>.
This is another line contains a<b.
このファイルを次のように変更したいと思います。
This is a test line with $VARIABLE1@$VARIABLE2.
This is a test line with $VARIABLE3.
This is a test line with $VARIABLE_UNKNOWN.
This is another line contains a<b.
で終わるすべての変数には、<>
大文字、数字、および下線のみが含まれます。
次の方法を使用することもできましたが、a<b
代わりにa$b
。
file_contents=$(<$file_path)
file_contents=${file_contents//</$}
file_contents=$(echo "$file_contents" | tr -d '>')
echo "$file_contents" > test.txt
sed
デバッグが非常に困難な複雑なコマンドを使用しないようにしています。この目標をどのように達成できますか?
答え1
これは個々の行を単純に置き換えるだけなので、これを実行するsedコマンドは複雑ではありません。
$ sed -E 's/<([[:upper:][:digit:]_]+)>/$\1/g' file
This is a line with $VARIABLE1@$VARIABLE2.
This is a line with $VARIABLE3.
This is a line with $VARIABLE_UNKNOWN.
This is another line contains a<b.
-E
またはsedにPOSIX sedがない場合:
sed 's/<\([[:upper:][:digit:]_]\{1,\}\)>/$\1/g' file
あなたのsedがPOSIXと互換性がない場合新しいものを買うただし、この特定のタスクには次のことができます。
sed 's/<\([A-Z0-9_][A-Z0-9_]*\)>/$\1/g' file
〜のように@chrisdaviesが指摘しました。<VAR1>27
しかし、それはおそらくあなたが実際に得ようとしなければならない結果ではないでしょう。その結果、$VAR127
次のいずれかを実際に目指す必要があります。
$ sed -E 's/<([[:alnum:]_]+)>/${\1}/g' file
This is a line with ${VARIABLE1}@${VARIABLE2}.
This is a line with ${VARIABLE3}.
This is a line with ${VARIABLE_UNKNOWN}.
This is another line contains a<b.
$ sed -E 's/<([[:alnum:]_]+)>/"${\1}"/g' file
This is a line with "${VARIABLE1}"@"${VARIABLE2}".
This is a line with "${VARIABLE3}".
This is a line with "${VARIABLE_UNKNOWN}".
This is another line contains a<b.
出力で何をしたいかによって異なります。
FWIW通常、人々はテキストにプレースホルダ文字列があるときにそれらを置き換えません。名前シェル変数は次に置き換えられます。コンテンツシェル変数です。それ以外の場合は、最初にシェル変数名でテキストを生成できますが、テキストにプレースホルダを使用することはどういう意味ですか?
答え2
< >
問題が「1つ以上の大文字、数字、および下線を含むがそれ自体に含まれていますが、「< >
で$
置き換えられたすべての文字列を変換したい」と定式化できる場合は、< >
次のようにします。
$ perl -pe 's/<([A-Z\d_]+)>/\$$1/g' file
This is a line with $VARIABLE1@$VARIABLE2.
This is a line with $VARIABLE3.
This is a line with $VARIABLE_UNKNOWN.
This is another line contains a<b.
これは-pe
「入力ファイルを一行ずつ読み、与えられたスクリプトを適用し-e
、各行を印刷する」という意味です。次に、代替演算子(s/OLD/NEW/
)をg
フラグと一緒に使用して、その行のすべての項目を置き換えます。最後に、正規表現は、文字<
の後に1つ以上の+
大文字のASCII文字(A-Z
)、ASCII1 10進数(\d
)、または_
末尾の下線()が続く文字を探します>
。これで、パターンは角かっこ()内にあるので、これを「キャプチャ」し、置き換えで([A-Z\d_]+)
参照できます。$1
したがって、一致を$
(エスケープする必要がある\$
)に置き換え、一致を次に置き換えます\$$1
。
少なくとも$PERL_UNICODE
この場合、環境変数が設定されていない限り、他の種類の10進数と一致します。このa
フラグを演算子に使用してs///
0123456789のみが一致することを確認するか、または\d
に置き換えます。0-9
0123456789
答え3
使用幸せ(以前のPerl_6)
~$ raku -pe 's:g/ \< ( <[A..Z0..9_]>+ ) \> /\$$0/;' file
繰り返しますが、これは@terdonの優れたPerlの答えをほぼ直接翻訳したものです。
喜びに、
- 正規表現修飾子(グローバルなど)は、「代替グローバル」形式を
g
提供するために、マッチャーの頭部にコロンの後に配置されます。s:g///
<[ ... ]>
認識フィールド内で山かっこで囲まれた角かっこを使用して、カスタム文字クラスを作成します。角括弧は、正規表現の原子および/または属性を一緒にグループ化するために単独で使用されます(下記の例を参照)。- 文字範囲は(たとえば)または
..
などの二重点として指定されます。A..Z
0..9
\<
Rakuは、英数字以外のアンダースコアではないすべての文字を引用するか(バックスラッシュ)、エスケープする必要があります。\>
- 数値キャプチャはPerlのように括弧でRakuで指定されますが、これらの数値キャプチャは代替
$0
フィールド内で開始して使用する必要があります。 - OPは間違った置換に言及しており、通常、特定の文字に対してバックスラッシュを要求することは問題になる可能性があります。助けるために、Rakuは、上記の代替項目(補間文字列など)を作成できる
{...}
ように、代替フィールドにコードブロックを使用できるようにします。{"\$$0"}
出力に対して単純な数学演算(合計など)を実行するのに非常に便利です。
入力例:
This is a line with <VARIABLE1>@<VARIABLE2>.
This is a line with <VARIABLE3>.
This is a line with <VARIABLE_UNKNOWN>.
This is another line contains a<b.
出力例:
This is a line with $VARIABLE1@$VARIABLE2.
This is a line with $VARIABLE3.
This is a line with $VARIABLE_UNKNOWN.
This is another line contains a<b.
最後に、@terdonは正規表現システムに関連するすべての問題の良い概要を提供し、正確に理解する必要があります。数字つまり、ASCII数字ですか、それともUnicode数字ですか?
Rakuは「Unicode対応」言語であることに誇りを持っており、下部の最初のリンクからRaku正規表現のための広範なUnicode文字クラスのリストを見つけることができます。したがって、楽の\d
数字の略語はUnicode 番号が含まれます。上記のように数字を列挙するか、または接続詞と組み合わせた文字クラスを使用して、次のように数字をASCII数字に0..9
サブセット/制限することができます。\d
<:ASCII>
&&
[<:ASCII> && \d]
~$ raku -pe ' s:g/ \< ( [ [<:ASCII> && \d] | <:Lu> | _ ]+ ) \> /\$$0/;' file
上記は<:Lu>
「Letters-uppercase」Unicode文字クラスです。必要に<:ASCII>
応じて、同じ方法を使用して「ASCII大文字」にサブセットすることもできます(または上記の角かっこを並べ替えて再グループ化することもできます)。
https://docs.raku.org/言語/regexes#Unicode_properties
https://www.unicode.org/terminology/digits.html
https://docs.raku.org/言語/regexes#接続先:_&&
https://docs.raku.org/言語/regexes
https://raku.org
答え4
使用gawk
:
$ awk '{print gensub(/<([[:alnum:]_]+)>/, "$\\1", "g")}' file
# Or
$ awk '{print gensub(/<(\w+)>/, "$\\1", "g")}' file
This is a line with $VARIABLE1@$VARIABLE2.
This is a line with $VARIABLE3.
This is a line with $VARIABLE_UNKNOWN.
This is another line contains a<b.
gensub() 関数では、角かっこ as を使用してサブパターンを記憶し、captured group
後で as を使用して参照できますbackreference
。\n
。
GNU awk
マニュアルから:
ジェンソプ()利用できない追加機能を提供します。息子()またはgsub():代替テキストに正規表現のコンポーネントを指定する機能。これは、正規表現で括弧を使用してコンポーネントを表示してから指定することによって行われます。'\N'代替テキストで窒素1 ~ 9 の数字です。