Shell 脚本 sed 错误:
无法查看/home/xx/htdocs/*/modules/forms/int.php
/bin/rm: 无法删除 `/home/xx/htdocs/tmp.26758': 没有那个文件或目录
我的 shell 脚本中出现错误。我不确定这个 for 循环是否有效,它的目的是爬上一个大的 PHP 文件目录树,并在每个 int.php 文件中添加一个函数,并进行一些验证。不要问我为什么这不是集中式/面向对象的,但事实并非如此。我从这里尽可能地复制了脚本:http://www.cyberciti.biz/faq/unix-linux-replace-string-words-in-many-files/
#!/bin/bash
OLD="public function displayFunction(\$int)\n{"
NEW="public function displayFunction(\$int)\n{if(empty(\$int) || !is_numeric(\$int)){return '<p>Invalid ID.</p>';}"
DPATH="/home/xx/htdocs/*/modules/forms/int.php"
BPATH="/home/xx/htdocs/BAK/"
TFILE="/home/xx/htdocs/tmp.$$"
[ ! -d $BPATH ] && mkdir -p $BPATH || :
for f in $DPATH
do
if [ -f $f -a -r $f ]; then
/bin/cp -f $f $BPATH
sed "s/$OLD/$NEW/g" "$f" > $TFILE && mv $TFILE "$f"
else
echo "Error: Cannot view ${f}"
fi
done
/bin/rm $TFILE
这样的通配符有用吗?我可以像这样检查树中的每个子目录吗?我是否需要对数组进行预编码并对其进行循环?我该怎么做呢?
此外,PHP 代码中的 $ 是否完全破坏了脚本?
我很困惑。
最佳答案
你的代码有问题
- 您不能使用 sed 以这种方式替换多行。
- 您正在 OLD 中使用
/
,它在s///
sed 命令中使用。这行不通 [ ! -d $BPATH ] && mkdir -p $BPATH || :
太可怕了。使用mkdir -p "$bpath"2>/dev/null
- 是的,这样的通配符会起作用,但只是因为您的字符串没有空格
- 双引号你的变量,否则你的代码将是非常危险的
- 单引号你的字符串,否则你不会明白你在转义什么
- 不要使用大写变量名,你可能会不小心替换 bash 内部变量
- 不要rm一个不存在的文件
- 您的备份将被覆盖,因为所有文件都命名为 int.php
假设您使用的是 GNU sed,我不习惯其他 sed 风格。
如果您不使用 GNU sed,则将 \n
替换为换行符(在字符串内)应该有效。
固定代码
#!/usr/bin/env bash
old='public function displayFunction(\$int)\n{'
old=${old//,/\\,} # escaping eventual commas
# the \$ is for escaping the sed-special meaning of $ in the search field
new='public function displayFunction($int)\n{if(empty($int) || !is_numeric($int)){return "<p>Invalid ID.</p>";}\n'
new=${new//,/\\,} # escaping eventual commas
dpath='/home/xx/htdocs/*/modules/forms/int.php'
for f in $dpath; do
[ -r "$f" ]; then
sed -i.bak ':a;N;$!ba;'"s,$old,$new,g" "$f"
else
echo "Error: Cannot view $f" >&2
fi
done
链接
关于linux - 如何在所有目录中的特定文件中循环 shell 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26006642/