Bash脚本疑难:使用sed批量修改PHP文件时无法添加换行符分隔声明语句
解决PHP文件批量添加带换行的
declare语句问题 你的问题核心在于两个关键点:一是sed的追加命令没法帮你拆分原有<?php和后续代码的结构,二是Linux与macOS的sed语法(尤其是换行处理、-i参数)存在差异,直接拼接换行符会失效。下面是修正后的兼容版脚本,以及关键修改的说明:
#!/bin/sh sed_cmd=sed # 适配macOS环境:优先用gnu-sed(需提前通过brew install gnu-sed安装) if uname | grep -q "Darwin"; then sed_cmd=gsed fi # 匹配行首的<?php,兼容后面带空格的情况 pattern='^<?php[[:space:]]*' declaration='declare(strict_types=1);' for file in $(find app -type f -iname '*.php'); do # 跳过已添加过declare语句的文件 if ! grep -qF "$declaration" "$file"; then # 用替换命令拆分结构,生成目标格式 "$sed_cmd" -i "s/$pattern/<?php\n$declaration\n/" "$file" fi done
关键修改详解
- 匹配模式优化:用
^<?php[[:space:]]*精准匹配文件开头的<?php(兼容后面带空格的写法,比如<?php),避免误匹配文件中间的字符串。 - 替换逻辑调整:不再用
a命令追加内容,而是用s替换命令,直接把匹配到的<?php(及后续空格)替换成<?php+换行+declare语句+换行,完美实现你想要的格式:<?php declare(strict_types=1); namespace Acme\Http\Middleware; - 跨系统兼容:
- 如果你不想安装gnu-sed,改用macOS自带的BSD sed,需要把
-i改成-i ''(BSD sed的-i必须指定备份后缀,空字符串表示不生成备份),同时换行符要写成\加换行的形式:sed -i '' "s/$pattern/<?php\ declare(strict_types=1);\ /" "$file"
- 如果你不想安装gnu-sed,改用macOS自带的BSD sed,需要把
- 重复添加防护:保留了原脚本的
! grep -qF "$declaration"判断,确保已处理过的文件不会被重复修改。
测试建议
修改脚本前,可以先对单个文件测试效果,确认格式符合预期后再批量执行:
# Linux或安装了gnu-sed的macOS gsed "s/^<?php[[:space:]]*/<?php\ndeclare(strict_types=1);\n/" test.php # macOS自带sed sed -E "s/^<?php[[:space:]]*/<?php\ declare(strict_types=1);\ /" test.php
内容的提问来源于stack exchange,提问作者Matt Komarnicki
相关产品推荐
相关产品推荐

