複数行を含むテキストファイルがあります。行の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つに置き換えます。$values
unknown1
unknown2
しかし、私は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
ソースファイルを台無しにした場合に備えてコピーを保管しています。