【问题标题】:Terminal and shell, defining a shorthand for: find with grep and replace with sed终端和外壳,定义简写:用 grep 查找和用 sed 替换
【发布时间】:2013-12-18 05:43:29
【问题描述】:

所以我尝试创建我的 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%%,所以一个函数更容易实现。

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

【问题讨论】:

  • 简单地说:grep -rl 'REPLACESTRING' ./ | xargs sed -i '.bak' 's/REPLACESTRING/REPLACED/g' 而不是分配命令到一个字符串然后尝试执行它。
  • 分词发生在变量扩展之前。试试eval,但要小心。
  • 不要将命令分配给字符串。命令是代码,字符串是数据,不要混合它们,在获得开明的大师地位之前不要做eval。如果要构建复杂的命令,请使用 函数

标签: bash sed terminal grep


【解决方案1】:
cmd_sr() { grep -rl 'REPLACESTRING' ./ | xargs sed -i '.bak' 's/REPLACESTRING/REPLACED/g' ; }

然后用cmd_sr代替$cmd_sr

【讨论】:

    【解决方案2】:

    您的字符串不包含一个命令,而是两个管道命令。 shell中有很多东西落后了。 Shell firs 制作管道,分叉子进程,将这个子进程中的标准输入重定向到这个管道,然后将exec 重定向到xargs。然后在主进程中 fork 另一个子进程,将这个子进程的 stdout 重定向到管道,并将exec 重定向到 grep。当您将 $cmd_sr 作为脚本 shell 中的行放置时,此命令中没有任何线索 | 但将其视为一个命令,因此 fork 并执行此命令。改为制作函数。

    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' {} +
    

    【讨论】:

    • 好的,你已经解释了我的解决方案在我发布之后。请在另一个问题中弥补我的任何其他解决方案,在此处报告,我将删除我的解决方案。
    • -execdir 在其他进程共享文件系统时优于-exec。
    • @user2987828:对不起,在你发布你的答案之前,我已经开始写我的答案了。较长的答案通常需要一些时间。
    • -exec vs execdir,我更关心包含空格的文件名而不是安全性。反正也可以用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 2014-02-11
    • 2011-09-04
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 2019-11-29
    相关资源
    最近更新 更多