パラメータ付きスクリプトでsedコマンドが失敗する

パラメータ付きスクリプトでsedコマンドが失敗する

ステップ2文字列編集を実行しようとしています。

  1. 文字列「ペイロード」と一致します。見つかった場合は、出力ファイルに示すように "#if #endif"コードを追加します。
  2. 次に、「payload」を含む行をコピーして「upper_payload」に置き換えて、「if endif」条件に貼り付けます。

入力ファイル:

Let's see if this works or not payload.
alskdjaslkdjn.
aslkdjbnalkgfjbaglbjbjdgfsbkgjbsg;
Also here is another_payload.
alskdjbnalgkjb.
kjhsdfjlkgfjlknbsgdfljkbgsbljk((*&)(&;

期待される出力ファイル:

Let's see if this works or not payload.
#if defined(NV_C2C_UPPER_PD)
Let's see if this works or not upper_payload.
#endif
alskdjaslkdjn.
aslkdjbnalkgfjbaglbjbjdgfsbkgjbsg;
Also here is another_payload.
#if defined(NV_C2C_UPPER_PD)
Also here is another_upper_payload.
#endif
alskdjbnalgkjb.
kjhsdfjlkgfjlknbsgdfljkbgsbljk((*&)(&;

複数のテキストファイルで実行できるように、シェルファイルに次のコードを書きました。

#!/bin/csh -f
sed -i '/payload/a #if defined(NV_C2C_UPPER_PD)\n#endif' $1
sed -i "/NV_C2C_UPPER_PD/a `sed -n '/payload/s/payload/upper_payload/p' $1`" $1

上記のシェルスクリプトを使用して次のコマンドを渡す場合:

> ./my_shell.sh test.txt

テキストファイルは次の出力に変更されます。

Let's see if this works or not payload.
#if defined(NV_C2C_UPPER_PD)
Let's see if this works or not upper_payload.
#endif
alskdjaslkdjn.
aslkdjbnalkgfjbaglbjbjdgfsbkgjbsg;
Also here is another_payload.
#if defined(NV_C2C_UPPER_PD)
Let's see if this works or not upper_payload.
#endif
alskdjbnalgkjb.
kjhsdfjlkgfjlknbsgdfljkbgsbljk((*&)(&;

また、端末に次のエラー/警告が表示されます。

sed: can't read Also here is another_upper_payload.: No such file or directory

出力から行が誤ってコピーされたため、2番目の「upper_payload」置換が間違っていることを確認できます。 「another_payload」を含む新しい行ではなく、最初の行をコピーします。

別のオプションを試しましたが、問題を解決できませんでした。助けてください。

答え1

sedの1つへの入力を生成するために別のプロセスを呼び出すのではなく、トリガー部分文字列()が見つかったらすぐにコマンドを使用して現在の行を再編成することをお勧めします。seds///payload

/payload/!b

s/.*/&\
#if defined(NV_C2C_UPPER_PD)\
&\
#endif/

s/payload/upper_&/2

上記の編集スクリプトは、sed最初にトリガー文字列を含むすべての行をスキップします。ラベルなしで使用すると(「branch」)、コマンドはbスクリプトの最後に移動します。

残りの行では、内容全体をそれ自体に置き換え、次の行に置き換え、#if元の行に戻し、次の#endif行に置き換えます。s///このコマンドは、上記のようにエスケープされている場合は改行文字を挿入するために使用できます(GNUではsedリテラル改行文字の挿入も許可されます\n)。

これにより、2番目の文字列が別の代替payload文字列の前に追加されます。upper_

このソリューションでは、トリガー文字列が 1 行に複数回発生しないか、最後の置換が正しい部分文字列を置き換えないと想定しています。

コマンドラインで、

sed -e '/payload/!b' \
    -e 's/.*/&\
#if defined(NV_C2C_UPPER_PD)\
&\
#endif/' \
    -e 's/payload/upper_&/2' file

または、スクリプトに別のスクリプトファイルを使用します。

sed -f script file

またはここでスクリプト文書を使用してください。

sed -f /dev/stdin file <<'SED_SCRIPT'
/payload/!b

s/.*/&\
#if defined(NV_C2C_UPPER_PD)\
&\
#endif/

s/payload/upper_&/2
SED_SCRIPT

またはGNUを使用してsed

sed -e '/payload/!b' \
    -e 's/.*/&\n#if defined(NV_C2C_UPPER_PD)\n&\n#endif/' \
    -e 's/payload/upper_&/2' file

結果:

Let's see if this works or not payload.
#if defined(NV_C2C_UPPER_PD)
Let's see if this works or not upper_payload.
#endif
alskdjaslkdjn.
aslkdjbnalkgfjbaglbjbjdgfsbkgjbsg;
Also here is another_payload.
#if defined(NV_C2C_UPPER_PD)
Also here is another_upper_payload.
#endif
alskdjbnalgkjb.
kjhsdfjlkgfjlknbsgdfljkbgsbljk((*&)(&;

答え2

あなたはこれを試すことができますsed

$ sed -i 's/\(.*\)\(payload\)\(.*\)/&\n#if defined(NV_C2C_UPPER_PD)\n\1upper_\2\3\n#endif/ ' input_file

\(.*\)\(payload\)ここでは、一致を2つのグループに分けて、戻り時に簡単に再参照できるようにします。

&変更されていない完全一致を返します

\1upper_\2ここで必要な順序でグループを返し、挿入がpayload許可されるupper_まで最初のグループが一致します。payload

出力

$ sed 's/\(.*\)\(payload\)\(.*\)/&\n#if defined(NV_C2C_UPPER_PD)\n\1upper_\2\3\n#endif/' input_file
Let's see if this works or not payload
#if defined(NV_C2C_UPPER_PD)
Let's see if this works or not upper_payload
#endif.
alskdjaslkdjn.
aslkdjbnalkgfjbaglbjbjdgfsbkgjbsg;
Also here is another_payload
#if defined(NV_C2C_UPPER_PD)
Also here is another_upper_payload
#endif.
alskdjbnalgkjb.
kjhsdfjlkgfjlknbsgdfljkbgsbljk((*&)(&;

答え3

ここにはすでに良い解決策がありますが、sed個人的にはawk次の解決策を好みます。

awk \
-v if='#if defined(NV_C2C_UPPER_PD)' \
-v endif='#endif' \
'
/payload/{
  line=$0
  gsub("payload","upper_payload",$0);
  printf "%s\n%s\n%s\n%s\n",$line,if,$0,endif
  next
}
1' file

答え4

POSIXlyを使用する1つの方法は次のとおりです。

sed -e 'p
  /payload/!d
  s//upper_&/
  i\
#if defined(NV_C2C_UPPER_PD)
  a\
#endif
' file

改行をエスケープしたくない場合は、POSIXlyに準拠しながら次のことを実行できます。

sed -e 'p
  /payload/!d
  s//upper_&/
  H;s/.*//;x;G
  s/^/#if defined(NV_C2C_UPPER_PD)/
  s/$/#endif/
' file

関連情報