次のようにPHPファイルのコードブロックを自動的にコメントアウトしたいと思います。
元のブロック:
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
新しいコメントブロック:
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
したがって、この行を2つのファイルに入れ、sedを使用して自動的に置き換えを行います。ところがインターネットで検索した結果、やっと見つけました。sedを使用して文字列をファイルの内容に置き換えるそしてsed - 文字列をファイルの内容に置き換えるつまり、ソースまたはターゲットスキーマだけが1つのファイルにあり、残りはオンラインファイルにあることを意味します。ただし、ファイルには両方のサンプルがありません。
それでは、交換する方法は何ですか? sedを使うべきか、それともawkを使うべきですか?
答え1
sed
このメソッドsed
はリテラル文字列を理解していないため、使用しないでください(参照sedを使用して正規表現のメタ文字を確実にエスケープすることは可能ですか?)、そのようなツールを使用してawk
リテラル文字列を理解することは実際に可能です。
GNUを使用したawk
複数文字のRS
合計ARGIND
:
$ awk -v RS='^$' -v ORS= '
ARGIND < 3 { a[ARGIND]=$0; next }
s = index($0,a[1]) {
$0 = substr($0,1,s-1) a[2] substr($0,s+length(a[1]))
}
{ print }
' old new file
this is
the winter
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
of our
discontent
または、次のいずれかを使用してくださいawk
。
$ awk '
FNR == 1 { a[++argind]=$0; next }
{ a[argind] = a[argind] ORS $0 }
END {
$0 = a[3]
if ( s = index($0,a[1]) ) {
$0 = substr($0,1,s-1) a[2] substr($0,s+length(a[1]))
}
print
}
' old new file
this is
the winter
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
of our
discontent
上記は以下の入力ファイルを使用して実行されました。
$ head old new file
==> old <==
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
==> new <==
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
==> file <==
this is
the winter
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
of our
discontent
答え2
patch
この目的のためにこのユーティリティを使用することをお勧めします。
diff
1. コマンドを使用してパッチファイルを作成します。
2つのファイルがあり、そのうちの1つに置き換えたいブロックが含まれているとします。
$ cat toreplace.txt
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
もう一つは交換したいブロックを含んでいます。
$ cat replacewith.txt
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
それらの間に状況に応じた違いを作成し、コンテンツをパッチファイルに入れます。
$ diff -c toreplace.txt replacewith.txt > patchfile
$ cat patchfile
*** toreplace.txt 2024-03-17 12:12:31.073270945 +0200
--- replacewith.txt 2024-03-17 12:12:45.276887865 +0200
***************
*** 1,4 ****
--- 1,7 ----
+ /* For the production version, the following codelines are commented
+ out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
+ */
2. パッチ適用
さて、これを元のファイルと見なしてください。
$ cat myfile
line before 1
line before 2
line before 3
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
line after 1
line after 2
line after 3
以前に作成したファイルを使用して、変更したいpatch
ファイルに対してコマンドを実行できます。patchfile
$ patch -cb myfile patchfile
patching file myfile
Hunk #1 succeeded at 4 (offset 3 lines).
- 旗が
-c
届く-c
「パッチファイルを状況に応じた違いとして解釈します(またはオプションが指定されている場合はユーティリティの違いの出力-C
)。」。- ないので厳密に要求されるわけではありません。「ユーティリティは、またはオプションによってオーバーライドさ
patch
れない限り、差分リストの種類を決定しようとする必要があります。」-c
-e
-n
- ないので厳密に要求されるわけではありません。「ユーティリティは、またはオプションによってオーバーライドさ
- オプション
-b
は次のとおりです。「違いを適用する前に、変更された各ファイルの元のコンテンツのコピーを、サフィックスが追加された同じ名前のファイルに保存してください。.orig
」- バックアップを作成したくない場合は、このフラグを削除できます。
3. 検証
それでは、元のファイルをパッチされたファイルと比較してみてください。
$ diff -c myfile{.orig,}
*** myfile.orig 2024-03-17 13:00:24.936142831 +0200
--- myfile 2024-03-17 13:13:48.882669202 +0200
***************
*** 1,10 ****
--- 1,13 ----
line before 1
line before 2
line before 3
+ /* For the production version, the following codelines are commented
+ out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
+ */
line after 1
line after 2
line after 3
答え3
sed -e '1s/.*/\/* For the production version, the following codelines are commented\nout\n&/g' -e '$s/.*/&\n*\//g'filename
output
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/