我想自动注释掉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);
*/
所以我打算将这些行放在两个文件中,并使用 sed 自动执行替换。然而,在网上搜索后,我只找到使用 sed 将字符串替换为文件内容和sed - 用文件内容替换字符串,这意味着只有源模式或目标模式位于一个文件中,其余部分位于在线文件中。但文件中没有两者的样本。
那么,如何进行更换呢?我应该使用 sed 还是 awk?
答案1
不要尝试使用sed
此方法,因为sed
它不理解文字字符串(请参阅是否可以使用 sed 可靠地转义正则表达式元字符),使用这样的工具awk
确实可以理解文字字符串。
使用 GNUawk
进行多字符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.使用命令创建补丁文件
假设您有两个文件,其中一个包含要替换的块:
$ 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
“将补丁文件解释为上下文差异(指定或选项时实用程序 diff 的输出-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);
*/