ファイルの1行にある2つの部分文字列を、コマンドラインの別のファイルにある2つの異なる行に置き換えます。

ファイルの1行にある2つの部分文字列を、コマンドラインの別のファイルにある2つの異なる行に置き換えます。

複数行を含むテキストファイルがあります。行の1つは次のとおりです。

fixed_stringA = 123, fixed_stringB = 456

2番目のテキストファイルがあります(やはり複数行を含む)。これらの2行は、次の順序でファイルの途中にあります。

found_value1=unknown1  
found_value2=unknown2

私の目標は、2番目のテキストファイルの2行を修正して、次のように読み込むことです。

found_value1=123  
found_value2=456

私の目標は、他のスクリプトを呼び出さずにコマンドラインでこれを行うことです。次のコードは機能しますが、短縮または改善できるかどうか疑問に思います。

value_variable=$(grep "fixed_stringA = [0-9]*, fixed_stringB = [0-9]*" first_file \
| sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/\1,\2/'); \
value1=$(echo $value_variable | cut -d "," -f 1); \ 
value2=$(echo $value_variable | cut -d "," -f 2); \
sed -i -E "s/unknown1/$value1/" second_file.txt; \
sed -i -E "s/unknown2/$value2/" second_file.txt

答え1

これらは2行にまとめることができます。

values="$(sed -n -E 's/^.*fixed_stringA\s*=\s*([0-9]+)\s*,\s*fixed_stringB\s*=\s*([0-9]+).*$/\1,\2/p' first_file)"
sed -i -E -e "s/unknown1/${values%,*}/" -e "s/unknown2/${values#*,}/" second_file.txt

最初の行は-nフラグと一緒にsedを使用して通常の出力を抑制し、ターゲット行を見つけて数値をキャプチャグループに抽出し、個別に印刷して変数\1に保存するように\2変換します。123,456$values

second_file.txt次の行では、forのコンマの前の内容とforのコンマの後のすべての内容を2つに置き換えます。$valuesunknown1unknown2

しかし、私はawkエクスポートがいつでも行を持つと確信しています。

答え2

経験的grepにwithを使用すると、独自にフィルタリングできるため、sedほぼ常に重複します。sedあなたの場合は、pコマンドのフラグを使用してs一致する場合にのみ印刷し、通常のd出力を抑制することを選択できます。

sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/\1,\2/p;d' first_file

次に、代替文字列を通常は予約済みスペースに保存して2番目のファイルに適用できますが、nsplace編集では機能しないため、2番目のコマンドが-i必要ですsed。最初のスクリプトを使用して2番目のスクリプト用のスクリプトを作成しましょう。

sed -i.bak $(sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/s_unknown1_\1_;s_unknown2_\2_/p;d' first_file) second_file

内部スクリプトは、s_unknown1_123_;s_unknown2_456_2番目のファイルに必要なスクリプトである出力を生成します。

-i.bak注:私は他のバージョンとの互換性に精通しており、sedソースファイルを台無しにした場合に備えてコピーを保管しています。

関連情報