终端和shell,定义了一个简写:用grep查找并用sed替换

时间:2013-12-02 13:33:33

标签: bash sed terminal grep

所以我尝试创建遍历当前目录的bash文件,并用新的字符串替换所有出现的字符串。

我创建了这一行,这在直接从终端运行时非常有效,但当它在.sh文件中时,它会出错。

cmd_sr="grep -rl 'REPLACESTRING' ./ | xargs sed -i '.bak' 's/REPLACESTRING/REPLACED/g'"`

然后在下一行用$cmd_sr执行上面一行。

显示以下错误。

grep: |: No such file or directory
grep: xargs: No such file or directory
grep: sed: No such file or directory
grep: '.bak': No such file or directory
grep: 's/REPLACESTRING/REPLACED/g': No such file or directory

现在我想我明白为什么会这样,grep试图在' ./'之后使用参数;作为文件,但显然失败了。

希望有人可以指出明显的错误,因为我正在努力找到问题。

===编辑===

对代码进行一些更新并将其替换为函数后......我有了这个

function sr {
    printf "Checking for $1 to replace with $2\n"
    grep -rl '%%APP_$1%%' ./ | xargs sed -i '.bak' 's/%%APP_$1%%/$2/g'
}

此函数从循环中调用,该循环执行循环遍历目录结构中要替换的字符串列表。

sr TITLE $title

其中$ title来自循环。因为我需要检查像%%APP_xxxx%%这样的字符串,所以函数更容易实现。

然而,随着更新,我现在没有收到错误,但我也没有得到字符串替换。是否可以查看输出以查看它正在循环的文件,或者可能在?

中找到这些字符串

2 个答案:

答案 0 :(得分:2)

cmd_sr() { grep -rl 'REPLACESTRING' ./ | xargs sed -i '.bak' 's/REPLACESTRING/REPLACED/g' ; }

然后使用cmd_sr代替$cmd_sr

答案 1 :(得分:1)

您的字符串不包含一个命令,而是包含两个管道命令。 shell中有很多事情要落后。 Shell firs生成管道,forks子进程,将此子进程中的stdin重定向到此管道,然后exec重定向到xargs。然后在主进程中分叉另一个子进程,将此子进程的stdout重定向到管道,并将exec重定向到grep。当您将$cmd_sr作为行放在脚本shell中时没有任何线索时,此命令中有|但是将其作为一个命令处理,因此fork和exec指向此命令。改变功能。

cmd_sr() {
    grep -rl 'REPLACESTRING' . |
        xargs sed -i '.bak' 's/REPLACESTRING/REPLACED/g'
}
cmd_sr

但我个人更喜欢

find . -type f -exec grep -q 'REPLACESTRING' {} \; -exec sed -i '.bak' 's/REPLACESTRING/REPLACED/g' {} +